Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Java] Android Bitmaps efficiënt gebruiken

Pagina: 1
Acties:

  • Steve04
  • Registratie: September 2011
  • Laatst online: 16:20
Hallo,

Ik ben bezig aan een app (voor tablet) dat een video stream binnenhaalt. De server is een andere Android app (IP WebCam) afkomstig van de Android Market die de camerabeelden beschikbaar stelt. Nu heb ik met WireShark gezocht hoe de video uitgewisseld word en blijkt dat het gewoon jpeg afbeeldingen (640x480) zijn die continue met een HTTP Get request worden opgevraagd, dus niet echt een video stream. Het gebruik van een reeds ontworpen en werkende app zoals bv.: tinycam is in mijn geval geen oplossing. De video moet ingebed worden in mijn app. Dan heb ik maar een HTTP-client geschreven die de afbeelding op bovenstaande wijze opvraagt en weergeeft in een ImageView. Het resultaat is aangezien het geen optimale werkwijze is verrassend goed, geen vertraging en duidelijk beeld. Alleen het beheer van de bitmaps laat alle wensen over, de Garbage Collector doet overuren en de app zit continue op low memory. Er mag dus niet veel gebeuren of daar is hij de: Out Of Memory Exception.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Override
public void run() {

    BufferedInputStream oInputStream;
    Bitmap showing = null;
    
    do{
        
        try {
            
            oHttpURLConnection = (HttpURLConnection)oUrl.openConnection();
            oInputStream = new BufferedInputStream(oHttpURLConnection.getInputStream());
            
// Hier wordt telkens een nieuwe bitmap aangemaakt en maakt 
// het geheel dus inefficiënt
            showing = BitmapFactory.decodeStream(oInputStream);
                
            if(showing != null){
                oHandler.obtainMessage(DECODE_RESULT_OK, showing).sendToTarget();
                                    
            }else{
                Log.w(TAG, "decode inputstream to bitmap failed");
            }
            
        } catch (IOException e) {
            
            Log.e(TAG, "download image failed",e);
            
        } finally{
            
            oHttpURLConnection.disconnect();    
            oHttpURLConnection = null;
        }
        
    }while(looping);
}


Als ik de bitmap decoder een reeds aangemaakte bitmap laat hergebruiken dat heeft de Garbage collectior minder werk, alleen blijft de app op low memory:

code:
1
GC_CONCURRENT freed 1254K, 17% free 10581K/12679K, paused 2ms+3ms


Alle tips, ervaringen, verbeteringen, noem maar op zijn welkom waarvoor dank !

Groeten Steve

  • cenix
  • Registratie: September 2001
  • Laatst online: 19:46
Ik vermoed dat er nog teveel (grote) objecten aangemaakt worden die kortstondig gebruikt worden.
Zie new openConnection, BufferedInputStream.
Wellicht kun je deze eenmalig maken (b.v. een persistent connection). Het hergebruik van de bitmap is in ieder geval al een stap in de goede richting.
Wellicht dat ddms (Dalvik Debug Monitor Server) je nog een step verder kan helpen.
Maak een large heap aan, want afhankelijk van hoeveel frames er gebuffered worden kan dit nogal oplopen, zie de Android documentatie, maar kort: android:largeHeap="true" in je application declaration.
Zomaar wat ideeen. Wellicht wordt elders in je code nog meer geheugen gealloceerd.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Steve04 schreef op vrijdag 10 mei 2013 @ 16:51:
Nu heb ik met WireShark gezocht hoe de video uitgewisseld word en blijkt dat het gewoon jpeg afbeeldingen (640x480) zijn die continue met een HTTP Get request worden opgevraagd
[...]
Alle tips, ervaringen, verbeteringen, noem maar op zijn welkom waarvoor dank !
Als je eens zoekt op mjpeg dan vind je allicht iets zinnigers (libraries o.i.d.).

Heb je per "frame" een GET gezien of een enkele GET? Want het zou me niets verbazen als je nu diverse "mjpeg streams" tegelijkertijd laat binnenfietsen in je app terwijl je bijv. alleen maar 't eerste frame decoded en toont waarna de rest van de data genegeerd wordt en je vrolijk een nieuwe GET gaat doen (mogelijk terwijl de vorige nog "doorloopt"?).

[ Voor 25% gewijzigd door RobIII op 10-05-2013 20:15 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Steve04
  • Registratie: September 2011
  • Laatst online: 16:20
Dit is wat WireShark heeft als ik de server benader vanuit mijn browser:

Afbeeldingslocatie: http://www.uploadarchief.net/files/download/wireshark1.png

De webpagina heeft een javascript dat via ajax een afbeelding laad "http://10.0.0.3:8080/shot.jpeg" en deze vervolgens toekent aan de source attribute van een image tag. Dus er wordt telkens een HTTP GET-request gestuurd en de response is een JPEG image.

@cenix daar ga ik zeker wat mee doen, bedankt.