2017-07-18 6 views
0

Im Verwenden von asyncTask, um einen Download-Fortschritt anzuzeigen, wird mein Download von einer Bibliothek namens "file-downloader" in meiner Haupttätigkeit durchgeführt. es ist Github Seite ist „https://github.com/wlfcolin/file-downloaderasyncTask onProgressUpdate funktioniert nicht beim zweiten Aufruf

meinen benutzerdefinierten Dialog zeigt, wenn ich auf meine angegebene Schaltfläche klicken, und laden Sie Aufgabe und progressBar beginnt, wenn i Download-Button in diesem benutzerdefinierten Dialog drücken alle, was in Ordnung ist und progressBar funktioniert gut.

aber wenn ich diesen Dialog verlasse und ein anderes Mal ich diesen Dialog aufrufen, funktioniert die Fortschrittsbalken nicht! ich speichern Download-Status in der Datenbank mit den fileDownloader Bibliothek Listener und eine andere Zeit ich aufrufen benutzerdefinierten Dialog liest es aus der Datenbank und erkennen DownloadProgress läuft derzeit, aber wir sehen keine Änderung in der Fortschrittsbalken des benutzerdefinierten Dialogfelds, was ist das Problem?

Aktivitätscode

public class MainActivity extends AppCompatActivity { 


    /* 
    /
    /some variables 
    /
    */ 

    public static int downloadedFile2SizePercent = 0 ; // downloaded file percent 
    public static int downloadingFileStatus = 0; // downloading status 
    Button myBtn ; 
    DownloadDialog dd; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main2); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    myBtn = (Button)findViewById(R.id.button22); 
    myBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      dd = new DownloadDialog(mContext,1); 
      dd.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 
      dd.show(); 
     } 
    }); 

    /* 
    /downloadingFileStatus value manages here by file downloader listeners correctly and saves as static variable and also in database 
    /downloadedFile2SizePercent value manages here by file downloader listeners correctly and saves as static variable 
    /
    */ 

    } 


} 

DownloadDialog Klasse

public class DownloadDialog extends Dialog implements View.OnClickListener{ 

public Context c; 
public Button download, delete; 
private ProgressBar pb; 
ProgressTask progressTask; 
private int downloadStatus; 
private String downloadLink; 
private int downloadID 

public DownloadDialog(Context a, int downloadId) { 
    super(a); 
    this.c = a; 
    this.downloadId = downloadId 
} 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.download_dialog); 
    download = (Button) findViewById(R.id.downloaddialot_downloadbtn); 
    delete = (Button) findViewById(R.id.downloaddialot_deletebtn); 
    download.setOnClickListener(this); 
    delete.setOnClickListener(this); 

    pb = (ProgressBar)findViewById(R.id.progressBar); 
    pb.setMax(100); 
    pb.setProgress(0); 

    //database is opend at mainActivity it's static 
    downloadStatus=Integer.parseInt(MainActivity.prDb.intSearch(downloadId));// detects download status --> 0 is "notDownloadedYet" and 
    // 1 is "downloading" and 2 is "downloaded" 
    downloadLink= MainActivity.puDb.intSearch(downloadId);//detects download link 

    progressTask = new ProgressTask(); 


    if(downloadStatus==1){ 
      pb.setProgress(MainActivity.downloadedFile2SizePercent);//this code line works every 2nd and after dialog invoking 
      progressTask.execute(true); 
      Toast.makeText(c,"test task progress for 2nd started", Toast.LENGTH_SHORT).show();//this code line works every 2nd and afterdialog invoking 
    } 

} 

@Override 
public void onClick(View v) { 

    switch (v.getId()) { 
     case R.id.downloaddialot_downloadbtn: 
        FileDownloader.start(downloadLink); // download task starts here 
        progressTask.execute(true); 
        Toast.makeText(c,"download task progress for 1nd started", Toast.LENGTH_SHORT).show(); 
      break; 

     case R.id.downloaddialot_deletebtn: 
      if(downloadStatus==2){ 
       // delete codes 
      } 
      break; 
    } 
} 


public class ProgressTask extends AsyncTask<Boolean, Integer, Boolean> { 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected Boolean doInBackground(Boolean... params) { 

     while (MainActivity.downloadedFile2SizePercent!=100){ 
       publishProgress(MainActivity.downloadedFile2SizePercent); 
     } 
     if(MainActivity.downloadedFile2SizePercent==100){ 
      publishProgress(MainActivity.downloadedFile2SizePercent); 
     } 

     return true; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     pb.setProgress(values[0]); 
    } 

    @Override 
    protected void onPostExecute(Boolean aBoolean) { 
     super.onPostExecute(aBoolean); 
     downloadStatus=2; //also saves in database by download listeners in mainActivity 
    } 

} 

} 

Antwort

0

Die Fortschrittsbalken wie irgendein anderes UI-Element kann nur von dem Haupt-UI-Thread verwaltet oder aktualisiert werden.

Es ist die zeitraubende Aufgabe, den Teil in einer AsyncTask auszuführen, dann kann dieser Task den Fortschrittsstatus in einer flüchtigen Variablen speichern, und dann kann der UI-Thread die Fortschrittsanzeige beispielsweise aktualisieren, indem er die flüchtige Variable liest Verwenden eines Timers.

+0

Sagen Sie, die Fortschrittsanzeige kann nicht von asynctask verwaltet werden, die im benutzerdefinierten Dialogfeld erstellt wurde? Also sagte ich für den ersten Dialog, der funktioniert! – roz

+0

Ich verstehe Ihren Code nicht wirklich gut. Es scheint ein schlechtes Design aus OOP-Sicht. Sie sollten die Verwendung von statischen vermeiden. Es wird angenommen, dass ein Dialog eine Information und nichts anderes zeigen sollte und in Ihrem Code scheint der Dialog den Hauptteil zu haben. –

0

können Sie alles über AsyncTask hier lesen: https://developer.android.com/reference/android/os/AsyncTask.html

Aber hier ist mein kleines Beispiel/Tutorial:

private class MyAsyncTask extends AsyncTask<Void, Integer, Void> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     // prepare your UI for the background task beginning 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     // do some long-running task... 

     // you can do partial updates like: 
     publishProgress(25); 
     /* more hard work */ 
     publishProgress(50); 
     /* even more hard work */ 
     publishProgress(75); 

     // and when you're done... 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     super.onProgressUpdate(values); 
     // update your UI with the current progress (values[0]) 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     // update your UI now that it's done 
    } 
} 

Das Schlüsselkonzept in Bezug auf AsyncTask zu verstehen ist, dass jede Methode außerdoInBackground() ausgeführt auf der UI-Thread (der Hauptthread) Das heißt, Sie können Ihre Benutzeroberfläche von diesen Anrufen aktualisieren.

doInBackground() wird jedoch auf einem anderen Thread ausgeführt. Das bedeutet, dass Sie hier teure Arbeit verrichten können, ohne die Benutzeroberfläche Ihrer App zu verlangsamen.

Natürlich muss all die harte Arbeit, die Sie in diesem Hintergrund-Thread machen, irgendwie zum UI-Thread führen (damit Sie es verwenden können). Das ist, was publishProgress() und die return Anweisung von doInBackground() sind. Wenn Sie publishProgress(someValue) aufrufen, ruft das System onProgressUpdate(someValue) für Sie auf. Wenn Sie return someValue aufrufen, ruft das System onPostExecute(someValue) für Sie auf.

Verwandte Themen