我对 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
函数?
我将不胜感激任何帮助...
谢谢!