Spanish Cargar nuevos item

Jorgelcr

Active Member
Licensed User
Longtime User
Hola,

En la app que estoy desarrollando me estoy encontrando que da con frecuencia error "La aplicacion se ha detenido", en una pantalla que cargo datos en un CustomListview.

Alguien sabe si este problema puede solucionarse cargando por partes el listado?

Alguien tiene algún ejemplo?

Gracias
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Jorge

Ese tipo de error "habitualmente" suele ser por cargar muchas imágenes en memoria, antes Android daba un "out of memory" , pero ultimamente me di cuenta que da ese de "la aplicación se ha detenido" .
Si estas cargando imagenes puedes cambiar el tipo de carga para reducir el peso de la misma, si no es tu caso, ponte en modo debug y ejecuta la aplicación, a veces dependiendo que tipo de error sale en el debug

Saludos
 

Jorgelcr

Active Member
Licensed User
Longtime User
Hola,

Si es mi caso, estoy cargando un listado de unas 20 imagenes, ¿sabes indicarme cuanto es el tamaño máximo aprox que podría soportar sin dar el error?

¿Como me recomendarías hacerlo?
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Jorge:

¿sabes indicarme cuanto es el tamaño máximo aprox que podría soportar sin dar el error?
Esto es facil y dificil saberlo :D, facil por que es la RAM del dispositivo donde lo ejecutes, y dificil por que no es la memoria que tu uses, si no la que estan utuilizando el resto de aplicaciones y servicios mas la que Android no pueda borrar :rolleyes: , asi que aunque los datos los tienes ahí ya ves que no es facil saberlo.

Yo te aconsejo que hagas una prueba simple, en el dispositivo que estas haciendolo y donde te da error, seguro que la carga la haces algo asi:
B4X:
Bitmap1 = LoadBitmap(Dir,"Nombre Imagen")

Para evitar los errores de memoria lo mejor es cargarlos asi:

B4X:
LoadBitmapSample(Dir,Nombre Imagen,AnchoMaximo,AltoMaximo)

El alto y ancho máximo no te compliques en darle un valor y pon un porcentaje del ancho y alto de la pantalla (50%x, 50%y), para hacer una prueba rápida puedes poner porcentaje, luego si tienes muy claro el valor que le vas a dar lo pones , te aconsejo que lo hagas en DIP por que así cubrirás las diferentes densidades de pantalla. Aunque ya veras que con los porcentajes se va el error.

Ponle unos valores muy bajos, no se, un 10% y mira si la calidad de la imagen es correcta para ti, y si no súbela hasta que te lo parezca pero evitando que te de el error.

Otra ocpción pero mucho mas compleja seria ver el alto de pantalla, donde tienes el cursor y cargar solo las imágenes que ves, no todas, pero esto no es facil.

Saludos
 

Jorgelcr

Active Member
Licensed User
Longtime User
hola,

Descargo las imágenes mediante el servicio imagedownloader, he implementado el código de ese servicio modificando el código del jobdone como el que pongo a continuación:

B4X:
Sub JobDone(Job As HttpJob)
    ongoingTasks.Remove(Job.JobName)
    If Job.Success Then
        Dim bmp As Bitmap = Job.GetBitmap
            
    
        If tasks.IsInitialized Then
            For i = 0 To tasks.Size - 1
            
                Dim link As String = tasks.GetValueAt(i)
                If link = Job.JobName Then
            
                    Dim iv As ImageView = tasks.GetKeyAt(i)
                
                    Dim b2 As Bitmap
                    b2.InitializeMutable(iv.Width,iv.Height)
    
                    Dim c As Canvas
                    c.Initialize2(b2)
                
                    Dim r1 As Rect
                    r1.Initialize(0,0,bmp.Width,bmp.Height)
                                
                    Dim xdif As Float = iv.Width / bmp.Width
                    Dim ydif As Float = iv.Height / bmp.Height

                    Dim NewX As Float = bmp.Width * xdif
                    Dim NewY As Float = bmp.Height * ydif
                
                    Dim NewZ As Float = (iv.Width + iv.Height) / (bmp.Width + bmp.Height)
                
                    Dim r2X As Float
                    Dim r2Y As Float
                    
                    If NewX > NewY Then
                        'Log("X")
                        r2X = bmp.Width * ydif
                        r2Y = NewY
                    Else
                        'Log("Y")
                          r2X = NewX
                        r2Y = bmp.Height * xdif
                    End If
                
                    If r2X > iv.Width Then
                        Dim NewRatio As Float = (iv.Width / r2X)
                        r2X = r2X * NewRatio
                        r2Y = r2Y * NewRatio
                    End If

                    Dim NewLeft As Float = ((iv.Width - b2.Width) / 2)
                    Dim NewTop As Float = ((iv.Height - b2.Height) / 2)
                
                    Dim r2 As Rect
                    r2.Initialize(NewLeft,NewTop,r2X,r2Y)
                                    
                    c.DrawColor(Colors.White)
                    c.DrawBitmap(bmp,r1,r2)
                    c = Null
                    cache.Put(Job.JobName, b2)
                    iv.SetBackgroundImage(b2)
                End If
        
            Next
        End If
    Else
        cache.Put(Job.JobName,bmp)
    
        If tasks.IsInitialized Then
            For i = 0 To tasks.Size - 1
            
                Dim link As String = tasks.GetValueAt(i)
                If link = Job.JobName Then
                    Dim iv As ImageView = tasks.GetKeyAt(i)
                    iv.SetBackgroundImage(bmp)
                End If
            Next
        End If
    
        'Log("Error downloading image: " & Job.JobName & CRLF & Job.ErrorMessage)
    End If
    Job.Release
End Sub

Con este código me redimensiona la imagen pero me da todo el rato el error de "la aplicacion se ha detenido"
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

A mi ese método que empleas para bajarte ficheros no me gusta y empleo otro que es mucho mas flexible con la libreria OkHtt y la clase OkHttpClient , pero cada uno emplea la que mas le gusta.

De un simple vistazo veo que cargas varios bitmap (no me he parado a analizar el código):
B4X:
Dim bmp AsBitmap = Job.GetBitmap
 im iv AsImageView = tasks.GetKeyAt(i)
 Dim b2 AsBitmap
 b2.InitializeMutable(iv.Width,iv.Height)
Dim iv AsImageView = tasks.GetKeyAt(i)
 iv.SetBackgroundImage(bmp)
Cada vez que haces eso cargas la memoria y como luego no lo descargas pues mucho peor.

Coge el bitmat que te bajes, lo salvas donde quieras (en un fichero), y luego lo cargas en tu imagen final haciendo el redimensionado que quieras pero cargando como te dije con

B4X:
 LoadBitmapSample(Dir,Nombre Imagen,AnchoMaximo,AltoMaximo)

Así será la única forma que no cargues la memoria

Saludos
 

Jorgelcr

Active Member
Licensed User
Longtime User
Utilizo el servicio imagedownloader para mostrar las imagenes porque pensaba que era mejor que descargar todas las imagenes en una carpeta y despues cargarlas. Tu tienes bastante experiencia si me aconsejas que lo haga de esta manera lo voy a intentar y te comento.

Muchas gracias.
 
Top