[Android] ProgressDialog toont niet meer

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Ik ben momenteel bezig met het debuggen van een Androidapplicatie die ik zo'n anderhalf jaar geleden voor het laatst aangeraakt heb. In die tijd heeft er ook niemand anders aan gewerkt, maar blijkbaar is er wel iets stuk gegaan: de progress dialog die ik ingebouwd had in de downloader class die ik gebouwd heb wil niet meer tonen.

Ik heb een class DownloadTask die is afgeleid van een class CommunicationTask (er is ook een UploadTask, vandaar). CommunicationTask is gedefinieerd als volgt:
Java:
1
public abstract class CommunicationTask extends AsyncTask<Void, Integer, CommunicationTask> implements Comparable<CommunicationTask> { ... }


Zoals je kan zien heb ik dus gewoon zoals het hoort een AsyncTask gemaakt zoals voor progressbars gebruikelijk is.

Mijn onProgressUpdate-method in de DownloadTask ziet er als volgt uit:
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
protected void onProgressUpdate(Integer... progress)
{
    MyApp app = MyApp.getInstance();  // Deze naamgeving even aangepast, reclame leek me niet nodig

    if (callingActivity != null && (dialog == null || !dialog.isShowing()))
    {
        dialog = new ProgressDialog(callingActivity);
        dialog.setTitle(app.getString(com.mycompany.android.myapp.R.string.dialog_downloading_title));
        dialog.setMessage(description);
        if (fileSize > -1)
        {
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.setMax(fileSize);
        }
        else
            dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setProgress(0);
        dialog.show();
    }
    if (dialog != null)
    {
        int p = progress[0];
        dialog.setProgress(p);
        if (p >= fileSize)
            dialog.dismiss();
    }
}


Simpelweg debuggen toont aan dat de method netjes gerund wordt. Bij de eerste keer kom ik netjes binnen die eerste if op regel 5 en maakt hij zoals verwacht de dialog aan. Ook komt hij aan bij de dialog.show() op regel 18 en voert deze succesvol uit. Echter wordt de dialog niet getoond. De tweede if op regel 20 wordt ook netjes binnengetreden, maar omdat de progress nog 0 is wordt de dialog niet gedismisst. Dit heb ik uiteraard gecheckt. ;) Bij de eerstvolgende call naar de method is alle data al binnen (het is maar een kleine file). De eerste if treden we niet meer binnen omdat dialog niet meer null is. De tweede wel, en omdat progress nu groter of gelijk aan de filesize is wordt de dialog (die tot dan toe nooit in beeld is geweest) weer gedismisst.

Het vreemde is dus dat dit anderhalf jaar geleden nog gewoon werkte. Het lijkt alsof een van de Android-updates sindsdien iets gesloopt heeft, maar ik zou niet weten wat dat kan zijn. Heeft iemand enig idee?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Zo op het eerste gezicht zie ik niets verkeerd... Wat zegt logcat bij het aanmaken van de dialog/showen? Weet je zeker dat de Context waar je de ProgressDialog mee maakt(callingActivity) goed is?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Het is wat lastig bijhouden als je niet precies weet wat je zoekt maar ik kan wel dit vinden:
07-24 14:47:55.724: INFO/WindowManager(246): WIN DEATH: Window{4145d8d0 Downloaden&#8230; paused=false}
07-24 14:47:55.734: INFO/WindowManager(246): WIN DEATH: Window{411d71e8 Downloaden&#8230; paused=false}
07-24 14:47:55.734: INFO/WindowManager(246): WIN DEATH: Window{4126df18 Downloaden&#8230; paused=false}

Het is een beetje de vraag of dat gerelateerd is want ik heb de app 3 keer op rij voorbij dat downloadpunt geduwd en dit is het enige tijdstip waarop er iets voorbij komt dat hiermee te maken heeft. Er komen in elk geval geen errors of warnings voorbij.

De Context is zeker weten goed.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Vreemd. Is de onCreate callback voor je Activity wel al aangeroepen? Voor die tijd kun je niets showen. Het is een beetje tasten in het duister zo. probeer anders een de simpele static show() methods van ProgressDialog, en kijk eens of je deze wel buiten de AsyncTask callbacks aan de praat krijgt.

De code die je gepost heb zou mijn inziens gewoon moeten werken...

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
EddoH schreef op woensdag 24 juli 2013 @ 15:23:
Vreemd. Is de onCreate callback voor je Activity wel al aangeroepen? Voor die tijd kun je niets showen. Het is een beetje tasten in het duister zo.
Bekend gevoel. :+

Die Activity is al netjes gestart. Het gaat gewoon om de hoofdactivity die ook het main menu toont. Na het starten van de activity wordt het profiel van de gebruiker even opnieuw binnengehaald vanaf een website, en dat is waar die CommunicationManager (die DownloadTasks weer aanroept) aan de beurt komt. Die activity draait dus al. Zou ook vreemd zijn als dat niet zo was omdat het voorheen natuurlijk wel gewoon werkte.
probeer anders een de simpele static show() methods van ProgressDialog, en kijk eens of je deze wel buiten de AsyncTask callbacks aan de praat krijgt.
Ik zal er eens mee spelen.
De code die je gepost heb zou mijn inziens gewoon moeten werken...
Sterker nog: dat hééft 'ie gewoon gedaan. 8)7

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Wordt de parent component van de ProgressBar wel getoond? Ik heb me ook wel eens een uur zoet gehouden met een niet-verschijnend element op een View en uiteindelijk bleek zijn parent (indirect) niet aan de Activity toegevoegd te zijn.

Wat zegt isShowing() als je deze na de show() aanroept?
Ik zie trouwens in de reference v17 dat isShown() wel bestaat, maar isShowing() niet, maar omdat je hier geen fouten over krijgt in logcat ga ik er even vanuit dat dat ergens tussen de door jou gebruikte versie van de ref en de huidige versie gewijzigd is.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Die view is gewoon zichtbaar. Het is namelijk geen progressbar maar een progressdialog, en die komt met de main activity gewoon in de main view AFAIK.

Ik heb isShowing() niet zelf aangeroepen maar heb hem in de debugger wel voorbij zien komen, en daar geeft 'ie na show() gewoon true aan.

Ik develop trouwens voor API level 10 (da's Android 2.3.3 en hoger). Geen idee of dat nog effect heeft, maar je zou denken dat het door die specificatie juist niet ineens vanzelf mis zou mogen gaan...

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Ah, een ProgressDialog *hoofd -> toetsenbord* Ik ben weer eens over dingen heen aan het lezen.

In dat geval, heb je show(this, "", "Loading") oid. al eens geprobeerd? Zou in principe niet uit mogen maken, maar wie weet.

En inderdaad wat je zegt, in je manifest staat de API level geconfigureerd waardoor alle Android versies weten hoe ze dingen moeten interpreteren.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Ik ben even een andere bug aan het debuggen maar ik kom net tijdens het testen daarvan wel toevallig dit tegen:
07-24 18:27:56.785: ERROR/SurfaceTexture(114): [Downloaden&#8230;] abandon: SurfaceTexture(0x0x1721248) has been abandoned!
07-24 18:27:58.857: ERROR/SurfaceTexture(114): [Downloaden&#8230;] abandon: SurfaceTexture(0x0x1721248) has been abandoned!
07-24 18:27:58.987: ERROR/SurfaceTexture(114): [Downloaden&#8230;] abandon: SurfaceTexture(0x0x1721248) has been abandoned!
07-24 18:27:59.507: ERROR/SurfaceTexture(114): [Downloaden&#8230;] abandon: SurfaceTexture(0x0x1721248) has been abandoned!

Deze post verder meer om het voor mezelf allemaal bij elkaar te houden dan om hulp te vragen, aangezien ik denk hier wel meer mee te kunnen vinden.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Wat me net opvalt: je hebt het er in de start post over dat de 2e keer dat onProgressUpdate wordt aangeroepen je file al gedownload is en de ProgressDialog gedismissed wordt. Is het niet gewoon zo dat je de hele dialog niet ziet omdat de UI thread nog niet eens de kans gekregen heeft om het ding te showen?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Nee, er zijn ook grotere files en die toont 'ie ook niet. :P Daarbij: ik ben aan het debuggen. Als ik show aanroep terwijl ik aan het steppen zijn verwacht ik dan op zijn minst dáár die dialog te zien. En zelfs als dat niet instant is: tegen de tijd dat hij wéér in onProgressUpdate komt zou hij toch genoeg tijd gehad moeten hebben voor die draw. Dat werkte anderhalf jaar geleden in elk geval wel prima zo. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

NMe schreef op woensdag 24 juli 2013 @ 20:58:
Nee, er zijn ook grotere files en die toont 'ie ook niet. :P Daarbij: ik ben aan het debuggen. Als ik show aanroep terwijl ik aan het steppen zijn verwacht ik dan op zijn minst dáár die dialog te zien.
Duidelijk verhaal hoor, maar ik denk niet dat je hem instant zult zien tijdens steppen: je zit in de UI thread, en ik denk niet dat show() een instant redraw gaat doen. Je zult hem hoogstens zien als je uit progressUpdate returned en de event loop verder afgehandeld wordt.

[ Voor 3% gewijzigd door EddoH op 24-07-2013 22:14 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Vandaar ook de zin die daarop volgde: ik zou dan op zijn minst een draw verwachten voordat ik in de volgende aanroep van die method ben.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Ik heb het spul wat opgesplitst:
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
@Override
protected void onPreExecute()
{
        Log.d("MyApp", "Starting download: " + url.toString());
        MyApp app = MyApp.getInstance();
        dialog = new ProgressDialog(callingActivity);
        dialog.setTitle(app.getString(com.mycompany.android.myapp.R.string.dialog_downloading_title));
        dialog.setMessage(description);
        if (fileSize > -1)
        {
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.setMax(fileSize);
        }
        else
            dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setProgress(0);
        dialog.show();
}

@Override
protected void onPostExecute(CommunicationTask result)
{
    if (dialog != null)
        dialog.dismiss();
}

@Override
protected void onProgressUpdate(Integer... progress)
{
    Log.d("MyApp", "Updating progress for " + description + " to " + Integer.toString(progress[0]));
    dialog.setProgress(progress[0]);
}

Nou showt hij wel maar handelt hij tussendoor geen progress af. Blijft domweg op 0 staan tot hij klaar is, en dan zie je hem naar 100% schieten en sluiten. 8)7

Deze method (die aangeroepen wordt vanuit mijn doInBackground) lijkt min of meer de boosdoener:
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
protected void executeTransfer()
{
    try {
        URLConnection ucon = url.openConnection();
        BufferedInputStream bis = new BufferedInputStream(ucon.getInputStream(), 8192);

        fileSize = ucon.getContentLength();

        ByteArrayOutputStream baf = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int progress = 0;
        int read;
        while ((read = bis.read(buffer, 0, 1024)) != -1) {
            baf.write(buffer, 0, read);
            if (callingActivity != null && isWaiting())
            {
                if ((fileSize > 0 && (progress % (fileSize / 20) == 0)) || (fileSize == -1 && progress == 0))
                    publishProgress(progress);
            }
            progress += read;
        }
        publishProgress(progress);

        result = baf.toByteArray();
        status.set(STATUS_COMPLETED);
        while (mgr.isPaused())
            Thread.sleep(50);
    } catch (Exception e) {
        if (errorCount++ < 3)
            executeTransfer();
        else
            status.set(STATUS_FAILED);
    }
}

Als ik bij wijze van test de executeTransfer-method bovenaan uitbreid met de volgende code, dan krijg ik wel een langzaam oplopenden progressbar:
Java:
1
2
3
4
5
for (int i = 0; i < 100; i++)
{
    publishProgress(i);
    Thread.sleep(100);
}

Dezelfde code onderin doet dat niet, ook niet als ik de if voor de regel publishProgress(progress); weghaal... Ik snap er niks meer van. De thread blockt blijkbaar niet want dan zou die teller ook niet werken. Het ligt niet aan de if die het blokkeert. Het ligt niet aan de sleep, want die heb ik ook uitgeprobeerd. De publishProgress-regel wordt ook gewoon netjes gerund. 8)7

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Vaag...
onProgressUpdate wordt dus niet aangeroepen na een publishProgress, behalve bij de testloop? Dan is op de een of andere manier toch echt je UI thread geblocked bij het downloaden, maar uit de code die je post kan ik niet halen waarom...

Wat doet die isWaiting()?

[ Voor 3% gewijzigd door EddoH op 25-07-2013 22:25 ]


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Hier lijkt me iets mis te gaan:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
        int progress = 0;
        int read;
        while ((read = bis.read(buffer, 0, 1024)) != -1) {
            baf.write(buffer, 0, read);
            if (callingActivity != null && isWaiting())
            {
                if ((fileSize > 0 && (progress % (fileSize / 20) == 0)) || (fileSize == -1 && progress == 0))
                    publishProgress(progress);
            }
            progress += read;
        }
        publishProgress(progress); 


publishProgress() wordt binnen de loop van het downloaden van je bestand alleen maar aangeroepen als aan de if statements voldaan wordt. Doe na progress += read eens een publishProgress().

De var progress is, op de laatste iteratie na, altijd gegarandeerd een veelvoud van 1024 (grootte van je buffer). Dat betekent dat, als de fileSize bekend is, (fileSize / 20) ook een veelvoud van 1024 moet zijn om aan de binnenste if statement te voldoen. Dat betekent dat je nooit je progressDialog ziet oplopen zo lang de exacte fileSize niet een veelvoud van 20480 bytes is.

Het is nog vroeg, ik kijk misschien weer volledig over dingen heen, maar dit zag ik even.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
EddoH schreef op donderdag 25 juli 2013 @ 22:25:
Vaag...
onProgressUpdate wordt dus niet aangeroepen na een publishProgress, behalve bij de testloop? Dan is op de een of andere manier toch echt je UI thread geblocked bij het downloaden, maar uit de code die je post kan ik niet halen waarom...
Dat kan ik wel uitleggen, maar wat ik niet begrijp is waarom hij dat in die testloop niet doet maar bij de werkelijke situatie wel.
Wat doet die isWaiting()?
Ik heb een Semaphore met één permit per task. Een task kan vervolgens blocking gemaakt worden, en alleen een blocking task moet die dialoog laten zien; non-blocking tasks zijn niet acuut nodig en kunnen op de achtergrond doorlopen. Ik heb dat opgelost door in mijn CommunicationTask-class een waitFor-method te maken:
Java:
1
2
3
4
5
6
7
8
9
10
11
public void waitFor(long timeout) throws InterruptedException
{
    this.priority = CommunicationManager.PRIORITY_URGENT;
    if (this.isTransfered())
        return;

    if (timeout == 0)
        waitLock.acquire();
    else
        waitLock.tryAcquire(timeout, TimeUnit.MILLISECONDS);
}

En om je vraag te beantwoorden, isWaiting doet dit:
Java:
1
2
3
4
public boolean isWaiting()
{
    return waitLock.availablePermits() == 0;
}

...en om helemaal volledig te zijn, de doInBackground-method die bovenstaande executeTransfer aanroept:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
protected DownloadTask doInBackground(Void... params)
{
    mgr.transferSemaphore.acquireUninterruptibly();
    try {
        executeTransfer();
    } catch (Exception e) {
        status.set(STATUS_FAILED);
    } finally {
        waitLock.release();
        mgr.transferSemaphore.release();
    }
    return this;
}

Die Semaphore in de manager is niet het probleem, die zorgt enkel dat er maar 5 down- of uploads tegelijk actief kunnen zijn.
Zyppora schreef op vrijdag 26 juli 2013 @ 09:22:
Hier lijkt me iets mis te gaan:

Java:
1
...


publishProgress() wordt binnen de loop van het downloaden van je bestand alleen maar aangeroepen als aan de if statements voldaan wordt. Doe na progress += read eens een publishProgress().
Als ik het me goed kan herinneren heb ik dit zo gebouwd omdat ondanks de buffer size van 1024 er toch één iteratie per byte was. Ik zal dat zo nog even dubbelchecken maar zelfs als dat niet zo was: zonder die if werkt het ook niet en wordt de progress niet geupdated.

Ik weet vrij zeker dat het aan mijn blocking semaphore ligt maar het absurde is dus dat die de UI-thread niet blokt voor een testloopje maar wél voor een real world situation. 8)7

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

NMe schreef op vrijdag 26 juli 2013 @ 15:45:
[...]

Als ik het me goed kan herinneren heb ik dit zo gebouwd omdat ondanks de buffer size van 1024 er toch één iteratie per byte was. Ik zal dat zo nog even dubbelchecken maar zelfs als dat niet zo was: zonder die if werkt het ook niet en wordt de progress niet geupdated.
Vreemd. Mijn ervaring is dat een BufferedInputStream.read() blokt totdat het maximale aantal bytes gelezen is dat opgegeven is (in jouw geval 1024).
Ik weet vrij zeker dat het aan mijn blocking semaphore ligt maar het absurde is dus dat die de UI-thread niet blokt voor een testloopje maar wél voor een real world situation. 8)7
Ik denk dan ook niet dat het aan je UI-thread ligt, of ten minste niet puur daaraan. Wat zit er in je fileSize variabele na de getContentLength() call?

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Topicstarter
Ga ik maandag even op terugkomen, ik zit nu eerst een weekend met de familie opgescheept. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.

Pagina: 1