我收到了来自强制关闭对话框报告的用户的大量错误报告,其中包含以下内容:
java.lang.ExceptionInInitializerError
at com.MyRequest.execute(MyRequest.java:59)
at org.nsdev.MySyncAdapter.onPerformSync(MySyncAdapter.java:90)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:164)
Caused by: java.lang.RuntimeException:
Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
现在,我一直试图找出如何最好地解决这个问题。在我的onPerformSync实现中,我创建了许多AsyncTasks并执行它们。我怀疑我的问题是我在从onPerformSync返回之前没有等待完成这些任务。我试着做以下事情:
Looper.prepare();
// Execute async tasks
Looper.loop();
然后我设置了一个计数器,当该计数器减少到零时,在异步任务的回调中调用Looper.myLooper()。quit()。
但是这样做会导致我的应用程序因以下运行时错误而更加崩溃:
java.lang.RuntimeException: Main thread not allowed to quit
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:175)
at android.os.Looper.quit(Looper.java:173)
at org.nsdev.MySyncAdapter$1.requestFinished(MySyncAdapter.java:89)
at com.MyAsyncTask.onPostExecute(MyAsyncTask.java:84)
at android.os.AsyncTask.finish(AsyncTask.java:417)
at android.os.AsyncTask.access$300(AsyncTask.java:127)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
知道如何正确完成同步吗?
答案 0 :(得分:4)
我知道这篇文章很老,但对于遇到这个帖子的其他人来说,在主线程上不调用looper.quit()呢?以下对于我来说,SyncAdpater服务产生了几个AsyncTasks,虽然可能有其他原因不能在性能方面做到这一点......
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
// AsyncTask... execute();
}
});
答案 1 :(得分:1)
其实你做不到。 AsyncTask使用主UI线程并依赖于那里没有的Handler和Looper。使用纯Thread实现,AsyncTask只能在活动中使用。
答案 2 :(得分:0)
abloc的响应解决了这个问题,但是这个解决方案的问题是UI冻结了,这个问题出现在Android 2.2和Android 2.3中。我找到的技巧是在我的班级SyncAdapter
中调用AsyncTask的构造函数并使用Looper.prepare()
:
/**
* Constructor. Obtains handle to content resolver for later use.
*/
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
mHandler = new Handler();
//Crear un dummy AsyncTask
new AsyncTask<Void, Void,String>() {
@Override
protected String doInBackground(Void... params) {
return null;
}
}.execute(null,null);
}