Question

J'ai reçu un grand nombre de rapports de bogues des utilisateurs signalés dans Force Close Dialogs qui indiquent quelque chose comme les suivants:

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)

Maintenant, j'ai essayé de comprendre comment je devrais mieux résoudre ce problème. À l'intérieur de mon implémentation ONPERFORMSYNC, je crée un certain nombre d'asynctasques et je les ai exécutés. Je soupçonne que mon problème est que je n'attends pas que ces tâches se terminent avant de revenir d'OnperformSync. J'ai essayé de faire ce qui suit:

Looper.prepare();

// Execute async tasks

Looper.loop();

Et puis j'ai configuré un compteur et lorsque ce compteur diminue à zéro, appelez Looper.mylooper (). Quit () à l'intérieur du rappel à partir des tâches asynchrones.

Mais cela fait que mon application s'écrase encore plus dur avec l'erreur d'exécution suivante:

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)

Une idée de comment accomplir correctement ma synchronisation?

Était-ce utile?

La solution

Je sais que ce post est vieux, mais pour ceux qui rencontrent ce fil, qu'en est-il de ne pas appeler Looper.quit () sur le fil principal? Ce qui suit fonctionne pour moi à partir d'un service Syncadpater engendrant plusieurs asynctases, bien qu'il puisse y avoir d'autres raisons de ne pas le faire en termes de performances ...

Handler h = new Handler(Looper.getMainLooper());
            h.post(new Runnable() {
                public void run() {

                    // AsyncTask... execute();
                }
            });

Autres conseils

En fait, vous ne pouvez pas. AsyncTask utilise le thread d'interface utilisateur principal et s'appuie sur le gestionnaire et le looper qui n'y est pas disponible. Utiliser la mise en œuvre du thread pur, AsyncTask ne doit être utilisé que dans les activités.

La réponse d'ABLOC résout le problème, mais le problème avec cette solution est que l'interface utilisateur gèle, ce problème est présent dans Android 2.2 et Android 2.3. L'astuce que j'ai trouvée a été d'invoquer un constructeur d'Asynctask dans ma classe SyncAdapter et utilisé 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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top