German xCustomListView ist sehr langsam bei nur 300 Datensätzen

Discussion in 'German Forum' started by JOTHA, Jul 14, 2018.

  1. JOTHA

    JOTHA Well-Known Member Licensed User

    Hallo zusammen,

    Erel schrieb bei der Veröffentlichung der xCustomListView, dass diese bis zu einer größeren Menge an Datensätzen noch sehr schnell im Aufbau sein sollte.

    Ich bin jetzt von einer "normalen" ListView, die ca. 300 Datensätze aus einer SQLite-Datenbank in weniger als 1 Sekunde aufgebaut hat, auf eine xCustomListView umgestiegen.

    Diese benötigt jetzt aber für den Aufbau der gleichen Datensätze ca. 34 Sekunden (das ist für die App aber entscheiden zu lange!) !!!

    Es geht dabei um die Darstellung folgender Informationen aus der SQLite:
    6 Textfelder und 2 Verlinkungen zu Bildern (diese liegen in einem internen Ordner vor).

    Hier ist der Code:
    Code:
    #Region  Project Attributes
        
    #ApplicationLabel: B4A Example
        
    #VersionCode: 1
        
    #VersionName:
        
    'SupportedOrientations possible values: unspecified, landscape or portrait.
        #SupportedOrientations: unspecified
        
    #CanInstallToExternalStorage: False
    #End Region

    #Region  Activity Attributes
        
    #FullScreen: False
        
    #IncludeTitle: True
    #End Region

    Sub Process_Globals

        
    Dim SQL1 As SQL
        
    Dim Cursor As Cursor

    End Sub

    Sub Globals
        
        
    Private xCustomListView As CustomListView
        
    Private Panel_003a_Label_Ueberschrift As Label  '-- eine Initialisierung ist zwar unnötig, aber bei der Ausführung der App wird ein ERROR generiert --
        Private Panel_003a_Label_001 As Label
        
    Private Panel_003a_ImageView_014 As ImageView
        
    Private Panel_003a_Label_002 As Label
        
    Private Panel_003a_ImageView_009 As ImageView
        
    Private Panel_003a_Label_014 As Label
        
    Private Panel_003a_Label_Hinweis As Label
        
    Private Panel_003a_Label_004 As Label
        
    Private Panel_003a_Label_IDNR As Label
        
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
        
    Log("Kopiere die Datenbank in File.DirRootExternal")

        
    File.Copy(File.DirAssets, "SQLite_MUSTER.sl3", _
                        
    File.DirRootExternal, "SQLite_MUSTER.sl3")
        
    Log("Datenbank in File.DirRootExternal kopiert!")

        
    If FirstTime Then
            SQL1.Initialize(
    File.DirRootExternal, "SQLite_MUSTER.sl3"True)
        
    End If
        
    If SQL1.IsInitialized = False Then
            SQL1.Initialize(
    File.DirRootExternal, "SQLite_MUSTER.sl3"True)
        
    End If
        SQL1.Initialize(
    File.DirRootExternal, "SQLite_MUSTER.sl3"True)

        
    Activity.LoadLayout("layout_003_datensaetze_zeigen")
        
        xCustomListView.Clear
        
    '-- Überschrift einfügen und View initialisieren --
        Panel_003a_Label_Ueberschrift.Initialize("CreateListItem")
        Panel_003a_Label_001.Initialize(
    "CreateListItem")  '-- eine Initialisierung ist zwar unnötig, aber bei der Ausführung der App wird ein ERROR generiert --
        Panel_003a_Label_002.Initialize("CreateListItem")
        Panel_003a_Label_014.Initialize(
    "CreateListItem")
        Panel_003a_Label_004.Initialize(
    "CreateListItem")
        Panel_003a_Label_IDNR.Initialize(
    "CreateListItem")
        Panel_003a_Label_Hinweis.Initialize(
    "CreateListItem")
        Panel_003a_ImageView_009.Initialize(
    "CreateListItem")
        Panel_003a_ImageView_014.Initialize(
    "CreateListItem")
        
        
    Cursor = SQL1.ExecQuery ("SELECT * FROM MUSTER_Tabelle")
            
        
    Try
            SQL1.BeginTransaction

            
    For i = 0 To Cursor.RowCount - 1
                
    Cursor.Position = i
                
            
    '-- Zähler für die Auswahlliste generieren --
                Dim Counter As String
                Counter = i +
    1
                
            
    '-- die xCustomListView aufbauen --
                xCustomListView.Add(CreateListItem(Panel_003a_Label_Ueberschrift.Text, Activity.Width, 315dip), ""&Cursor.GetString("IDNR")&"")
                
            
    '-- wenn keine Internet-Adresse vorhanden ist -- Feld007 --
                If Cursor.GetString("Feld007") = "- keine Internet-Adresse -" Then
                    Panel_003a_Label_Ueberschrift.Text = 
    "  "&Counter&". Datensatz ist OHNE Internet-Zugang"
                    Panel_003a_Label_Ueberschrift.Color = 
    Colors.Red
                
    Else If Cursor.GetString("Feld007") = "" Then
                    Panel_003a_Label_Ueberschrift.Text = 
    "  "&Counter&". Datensatz ist OHNE Internet-Zugang"
                    Panel_003a_Label_Ueberschrift.Color = 
    Colors.Red
                
    Else
                    Panel_003a_Label_Ueberschrift.Text = 
    "  "&Counter&". Datensatz ist MIT Internet-Zugang"
                    Panel_003a_Label_Ueberschrift.Color = 
    Colors.Blue
                
    End If
                
            
    '-- Daten_in_die_xCustomListView_einfuegen --
                Daten_in_die_xCustomListView_einfuegen
                
    Log("-----------------------------------------------------------------------------")
                
    Log(""&Counter&". Datensatz gelistet")

            
    Next
            SQL1.TransactionSuccessful
        
    Catch
            
    Log(""&LastException.Message&"")
        
    End Try
        SQL1.EndTransaction
        
    Cursor.Close

    End Sub

    Sub xCustomListView_ItemClick (Index As Int, Value As Object)
        
    Activity.Title = Value
        xCustomListView.AsView.BringToFront
    End Sub

    Sub Daten_in_die_xCustomListView_einfuegen

    '-- Daten in die Textelder zuweisen --
        Panel_003a_Label_001.Text = ""&Cursor.GetString("Feld001")&""
        Panel_003a_Label_002.Text = 
    "Benutzer:"&CRLF&""&Cursor.GetString("Feld002")&""
        Panel_003a_Label_004.Text = 
    "Kategorie:"&CRLF&""&Cursor.GetString("Feld004")&""
        Panel_003a_Label_IDNR.Text = 
    "ID: "&Cursor.GetString("IDNR")&""
            
    '-- Eigenes Bild zuweisen -- Feld014 --
        Log("Eigenes Bild zuweisen - Feld014: "&Cursor.GetString("Feld014")&"")
        
    If File.Exists(File.DirAssets, ""&Cursor.GetString("Feld014")&""Then
            Panel_003a_Label_014.Text = 
    "Ein Bild ist vorhanden"
            Panel_003a_ImageView_014.Bitmap = 
    LoadBitmap(File.DirAssets, ""&Cursor.GetString("Feld014"))
            Panel_003a_Label_014.Typeface = 
    Typeface.DEFAULT
        
    Else
            Panel_003a_Label_014.Text = 
    "Es ist KEIN Bild vorhanden!"
        
    End If
                
    '-- Kategorie-Icon zuweisen -- Feld009 --
        Log("Kategorie-Icon zuweisen - Feld009: "&Cursor.GetString("Feld014")&"")
        
    If File.Exists(File.DirAssets, ""&Cursor.GetString("Feld009")&""Then
            
    Log("If FILE EXISTST ==> "&File.Exists(File.DirAssets, ""&Cursor.GetString("Feld009")&"")&"")
            Panel_003a_Label_014.Text = 
    "Ein Bild ist vorhanden"
            Panel_003a_ImageView_009.Bitmap = 
    LoadBitmap(File.DirAssets, ""&Cursor.GetString("Feld009"))
            Panel_003a_Label_014.Typeface = 
    Typeface.DEFAULT
        
    Else
            Panel_003a_Label_004.Text = 
    "Es ist KEIN Kategorie-Bild vorhanden!"
            
    Log("Inhalt von Feld009: "&Cursor.GetString("Feld009")&"")
            
    Log("Es ist KEIN Kategorie-Bild vorhanden!")
        
    End If

    End Sub

    Sub CreateListItem(Text As String, Width As Int, Height As Int) As Panel
        
        
    Dim p As Panel
        p.Initialize(
    "")
        p.SetLayout(
    00, Width, Height)
        p.LoadLayout(
    "layout_003a_inhalt_p3_xclv3")
        Panel_003a_Label_001.Text = Text
        
    Return p
        
    End Sub

    Sub Activity_Resume
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
    End Sub
    Ich habe eine kleine Beispiel-App als zip-Datei zum Testen gepackt, aber leider kann ich diese nicht uploaden, da sie zu groß ist (743 kB). --> The uploaded file is too large. Gerne sende ich die Datei per Mail zu.

    Kann mir jemand sagen woran das liegt, das es soooo lange dauert?
     
  2. klaus

    klaus Expert Licensed User

    Versuche mal die Objects Datei in der Projekt Datei zu löschen, in manchen Fällen macht das einen Unterschied.
    Ich habe kaum mit xCustomListView gearbeitet, aber trotz dem, 34 Sekunden kommt mir sehr langsam vor.
     
  3. JOTHA

    JOTHA Well-Known Member Licensed User

    Hallo Klaus, kannst Du mir kurz erklären, was Du damit meinst?
     
  4. DonManfred

    DonManfred Expert Licensed User

    Entferne mal die 300 Transactions, den trycatch block.
    Es hilft alles nichts wenn du nicht verstanden hast wie das mit den Objekten funktioniert die in einem Layout sind welches innerhalb von CreateItem geladen wird.
     
  5. klaus

    klaus Expert Licensed User

    In dem Project Ordner, wo die xxx.b4a Datei gespeichert ist, sint noch zwei Ordner drin.
    Files und Objects, in manchen Fällen sind da grössere Dateien drin.
     
  6. JOTHA

    JOTHA Well-Known Member Licensed User

    Danke für deine Hilfe, Klaus.
    Jetzt habe ich verstanden, was Du gemeint hast.

    Ich habe den Objects-Ordner vollständig gelöscht und dann neu Kompiliert ... logischerweise hat die IDE dann den Ordner neu angelegt.
    Zuvor habe ich nachgeschaut, welche Eigenschaften der Objects-Ordner hatte: 30 Dateien in 18 Ordnern mit 2,32 MB. Nach dem Kompilieren hat sich praktisch nichts verändert.

    Die anschließend gepackte zip-Datei hat wieder eine Größe von 745 kB.
     
  7. klaus

    klaus Expert Licensed User

    Ich meinte den Objects Ordner bevor dem zippen zu löschen.
    Bei jedem kompilieren wird der wieder neu erstellt.
     
  8. JOTHA

    JOTHA Well-Known Member Licensed User

    ... ach so, wegen dem upload!

    Jetzt hats geklingelt!
    Das habe ich jetzt gemacht und wollte im Anhang die zip-Datei zum Testen hochladen, aber wieder die gleiche Meldung, weil die Datei immer noch 666kB groß ist.

    Zur Ausführung der App brauche ich aber den Files-Ordner, da in diesem die Icons sind, die in der xCustomViewList angezeigt werden sollen, sonst kommt eine Fehlermeldung ...

    ... also habe ich jetzt einfach ein paar Icons aus dem Files-Ordner gelöscht und dann mit 7-ZIP gepackt, jetzt kommen zwar auch Fehlermeldungen, aber zum Testen müsste es reichen.

    Ich danke Dir vielmals für deine Hilfe!

    Ich denke aber, das sich das Problem mit dem langsamen Aufbau mit "lazy" (aus dem Tutorial-Video) lösen lässt.
     

    Attached Files:

  9. klaus

    klaus Expert Licensed User

    Ich hab ein bisschen mit deinem Programm gespielt.
    Habe alle Log kommentiert.
    Auf meinem Galaxy S8 brucht der Aufbau ungefähr 4 - 5 Sekunden.
    Ich habe die Animation Duration in den Layouts auf 0 gesetzt.

    Beiliegend das Programm mit meinen Versuchen.
     

    Attached Files:

    • New.zip
      File size:
      352.4 KB
      Views:
      9
  10. Filippo

    Filippo Expert Licensed User

    Hallo Jürgen,

    4 tips von mir:
    1) verwende LoadBitmapResize oder LoadBitmapSample statt LoadBitmap
    2) lade nicht den Layout "layout_003a_inhalt_p3_xclv3", sondern erstelle es immer per code, es geht viel schneller
    3) verwende nicht DirRootExternal (ab Android 6+ Berechtigungsprobleme), sondern DirDefaultExternal
    4) In Manifest habe ich diese Zeile "SetApplicationAttribute(android:largeHeap, "true")" hinzugefügt, sonst kommt "memory-fehler"
     
    KMatle likes this.
  11. JOTHA

    JOTHA Well-Known Member Licensed User

    Hallo Klaus,
    vielen Dank für deinen Test!

    Bei meinem Smartphone dauert dieser Vorgang mit deinen Änderungen ca. 9 Sekunden (... es hat ja nicht jeder ein S8 ;)).

    Das Auskommentieren einer "Log-Zeile" bringt ca. 1 Sekunde Zeitersparnis. Bei der Anzahl der Log's summiert sich das natürlich ...

    Am meisten bremsen diese 2 Zeilen:
    Code:
    Sleep(1)
    Label1.Text = 
    "Der "&(i +1)&". Datensatz wird eingelesen"
    ... dadurch dauert alles über 20 Sekunden länger!
    --> aber ohne irgend eine Information im Display sind sogar "nur" 9 Sekunden für einen User zu lange ...

    Ich werde jetzt mal die Tipps von Filippo (siehe oben: LoadBitmapResize und SetApplicationAttribute(android:largeHeap, "true")) ausprobieren, um zu sehen, was diese noch an Geschwindigkeitsvorteilen bringen könnten.

    Vielen Dank Filippo und Klaus für eure Unterstützung!
     
  12. JOTHA

    JOTHA Well-Known Member Licensed User

    Vielen Dank DonManfred für deine Hinweise!
    Ich habe das was Du mir empfohlen hast getestet, leider hat es keinen merklichen Geschwindigkeitsvorteil gebracht ...
     
  13. Filippo

    Filippo Expert Licensed User

    Dieser Tipp bringt keine Geschwindigkeitsvorteile, es nur speicher schonend.
    Geschwindigkeitsvorteile bringt nur Tipp 2!
     
  14. JOTHA

    JOTHA Well-Known Member Licensed User

    Danke Filippo, ich habe das gerade eben getestet:
    Code:
    Panel_003a_ImageView_014.Bitmap = LoadBitmapResize(File.DirAssets, Cursor.GetString("Feld014"), 40dip40dipTrue)
    ... dauert sogar 1 Sekunde länger ...
    Code:
    Panel_003a_ImageView_014.Bitmap = LoadBitmapSample(File.DirAssets, Cursor.GetString("Feld014"), 40dip40dip)
    ... dauert 8,93 Sekunden ... aber gegenüber 9,13 Sekunden ist das ja nun wirklich kein Geschwindigkeitsvorteil ... ;)

    Jetzt baue ich mal den Code um mit deinem Tipp 2) lade nicht den Layout "layout_003a_inhalt_p3_xclv3"
    Da bin ich gespannt ...
     
  15. klaus

    klaus Expert Licensed User

    Dass LoadBitmapResize länger braucht als LoadBitmap hatte Ich bei menen Tests auch gesehen.
    Ich hatte auch mal versucht die Bitmaps nicht zu lesen, brachte aber auch keinen grossen Vorteil.
    Lazy loading bringt bestimmt etwas, habe es aber noch nie versucht.
    Ich muss auch zugestehen dass Ich xCustumView auch nicht verwende.
     
  16. MaFu

    MaFu Well-Known Member Licensed User

    Das könntest Du deutlich entschärfen indem Du die Info nur bei jedem 10ten oder 20ten Datensatz aktualisierst.
    Code:
    If i Mod 10 = 0 Then
        Sleep(
    1)
        Label1.Text = 
    "Der "&(i + 1)&". Datensatz wird eingelesen"
    End If
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice