2017-07-18 81 views
0

即时通讯使用asyncTask显示下载进度,我的下载将通过我主要活动中的一个名为“file-downloader”的库完成。 它的GitHub的页面为“https://github.com/wlfcolin/file-downloaderasyncTask onProgressUpdate无法在第二次调用

我的自定义对话框显示当我点击我的指定的按钮,下载任务,当我在这个自定义对话框 所有的事情是确定和进度正常工作按下载按钮,进度条开始。

但是当我解雇这个对话框和另一次我调用这个对话框progressBar不起作用! 我使用fileDownloader库监听器保存数据库中的下载状态,并且当我调用从数据库 读取的自定义对话框并检测到downloadProgress当前正在运行但我们看不到自定义对话框的progressBar中的更改时,有什么问题?

活性代码

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类

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 
    } 

} 

} 

回答

0

进度条,就像任何其他UI元素只能被管理或在主UI线程更新。

这是耗时的任务,应该在AsyncTask中运行的部分,然后该任务可以将进度状态保存在易失性变量中,然后UI线程可以定期更新读取易失性变量的进度条,例如使用计时器。

+0

你说进度条不能由自定义对话框中的asynctask管理吗?所以我说冷杉对话框调用它的作品! – roz

+0

我不太了解你的代码。从OOP的角度来看这似乎是一个糟糕的设计。你应该避免使用静态的。假设一个对话框应该显示一个信息,而不是其他任何东西,并且在你的代码中,对话框似乎是主要部分。 –

0

你可以阅读所有关于AsyncTask这里:https://developer.android.com/reference/android/os/AsyncTask.html

但这里是我的简单的例子/教程:

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 
    } 
} 

的关键概念关于AsyncTask理解的是,除了doInBackground()每个方法执行上UI线程(主线程)。这意味着您可以自由地从这些调用中更新您的用户界面。

doInBackground()然而,在不同的线程上执行。这意味着您可以在这里进行昂贵的工作,而不会减慢应用程序的用户界面。

当然,您在后台线程上所做的所有辛苦工作都需要以某种方式进入UI线程(以便您可以使用它)。这就是publishProgress()returndoInBackground()的声明。当您拨打publishProgress(someValue)时,系统将为您调用onProgressUpdate(someValue)。当你return someValue,系统将为你调用onPostExecute(someValue)