0

我对 Android 很陌生,但我还不知道如何做一些事情。我的应用程序有一个活动,onCreate我需要从远程服务器异步获取一些数据并对其进行处理。我有一个不同的类,一个服务,它检索数据并使用它。我也想通知用户工作的进展,所以我正在实现委托模式。

所以,我的活动看起来像:

public class HomeActivity extends FragmentActivity implements  UpdateLibraryDelegate{

        ....

      protected void onCreate(Bundle savedInstanceState) {

        ....

       UpdateLibraryTask updateLibraryTask = new UpdateLibraryTask();
       updateLibraryTask.setUpdateLibrarayDelegate(this);
       updateLibraryTask.execute();

   }

   private class UpdateLibraryTask extends AsyncTask<Void, Void, Void>{

    private UpdateLibraryDelegate updateLibraryDelegate;
    @Override
    protected Void doInBackground(Void... params) {
        myService.setUpdateLibraryDelegate(updateLibraryDelegate);
        myService.updateLibrary();
        return null;
    }

    public void setUpdateLibrarayDelegate(UpdateLibraryDelegate updateLibraryDelegate){
        this.updateLibraryDelegate = updateLibraryDelegate;
    }

}

/**DELEGATION METHODS**/
@Override
public void startDownloadingLibrary() {         
...
}
@Override
public void endDownloadingLibrary() {           
...
}
@Override
public void processingLibrary(final int progress) {  
}

我的服务有这样的东西:

 public void updateLibrary(){
    ...
    if(updateLibraryDelegate!=null){
         updateLibraryDelegate.startDownloadingLibrary();   
     }
    get(library_client, url, null, library_response_handler);
 }
 public JsonHttpResponseHandler library_response_handler = new JsonHttpResponseHandler() {
  @Override
    public void onSuccess(JSONObject jsonObject)
    {
        if(updateLibraryDelegate!=null){
            updateLibraryDelegate.endDownloadingLibrary();
        }
            for(...){
              //PROCESSING DATA
              updateLibraryDelegate.processingLibrary(process);
             }
    }
 }

有了所有这些代码,它似乎工作正常,委托函数在他们应该的时候被调用。当我尝试在 UI 上显示任何内容时,问题就出现了。如果我试试这个:

  @Override
  public void startDownloadingLibrary() { 
       if(progressDialog==null){
             progressDialog = new ProgressDialog(ctx);
       }

        progressDialog.setProgress(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage("Downloading Stories, This may take a while...");

        progressDialog.show();
 }

我得到一个例外:

09-23 14:08:00.850: E/AndroidRuntime(11336): FATAL EXCEPTION: AsyncTask #1
09-23 14:08:00.850: E/AndroidRuntime(11336): java.lang.RuntimeException: An error occured while executing doInBackground()
09-23 14:08:00.850: E/AndroidRuntime(11336):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-23 14:08:00.850: E/AndroidRuntime(11336):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-23 14:08:00.850: E/AndroidRuntime(11336):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-23 14:08:00.850: E/AndroidRuntime(11336):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-23 14:08:00.850: E/AndroidRuntime(11336):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-23 14:08:00.850: E/AndroidRuntime(11336):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-23 14:08:00.850: E/AndroidRuntime(11336):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-23 14:08:00.850: E/AndroidRuntime(11336):    at java.lang.Thread.run(Thread.java:841)
09-23 14:08:00.850: E/AndroidRuntime(11336): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-23 14:08:00.850: E/AndroidRuntime(11336):    at android.os.Handler.<init>(Handler.java:197)

我发现这是因为我在不是 UI 线程的线程上运行该方法,解决方案是:

    public void startDownloadingLibrary() {
        new Thread(){
            public void run(){
                HomeActivity.this.runOnUiThread(new Runnable(){

                    @Override
                    public void run() {
                            if(progressDialog==null){
                                progressDialog = new ProgressDialog(ctx);
                            }

                               progressDialog.setProgress(ProgressDialog.STYLE_SPINNER);
                               progressDialog.setMessage("Downloading Stories, This may take a while...");

                            progressDialog.show();

                    }

                });
            }
        }.start();
}

但这并没有像我预期的那样工作,虽然委托函数被正确调用,但run方法中的代码在数据处理完成之前不会执行。

通知用户异步进程进度的正确方法是什么?

有没有办法在我的委托函数上显示一个对话框而不使用该runOnUiThread函数?

我将不胜感激任何帮助...

谢谢!

4

1 回答 1

1

您可能应该实现 asyncTask 的 onPreExecute onProgressUpdate 和 onPostExecute。因此,您可以在任务开始之前开始显示对话框,调用 publishProgress 以显示进度,并在完成后关闭对话框。

有关更多信息,请查看http://developer.android.com/reference/android/os/AsyncTask.html

希望这会帮助你。

于 2013-09-23T14:49:41.083 回答