Android上代表模式的问题

时间:2013-09-23 13:19:06

标签: android

我在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功能的情况下在我的委托功能上显示对话框?

我很感激任何帮助...

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

希望这会对你有所帮助。