Почему метод PostExecute AsyncTask не запускается в потоке пользовательского интерфейса? - PullRequest
3 голосов
/ 15 марта 2012

У меня есть вложенный внутренний класс, который расширяет AsyncTask для выполнения запроса в фоновом режиме. В методе post execute я вызываю родительский метод для обновления представления примерно так:

private class QueryRunner extends AsyncTask<Void,Void,Cursor> {

  @Override
  protected Cursor doInBackground(Void... voids)
  {
     return getContentResolver().query(LeadContentProvider.buildUri(app.getEntityId()),new String[]{LeadContentProvider._ID},null,null,LeadContentProvider.LEAD_STATUS_DATETIME +" desc");
  }

  @Override
  protected void onPostExecute(Cursor c)
  {
     onCursorLoaded(c);
  }
}

Метод onCursorLoaded выглядит следующим образом:

private void onCursorLoaded(Cursor c)
{
  mPagerAdapter = new LeadDetailsFragmentPagerAdaper(getSupportFragmentManager());
  mPager.setAdapter(mPagerAdapter);
  mPager.setCurrentItem(iIndex, false);
}

В большинстве случаев это работает нормально, но у некоторых пользователей возникают сбои с этой трассировкой стека:

java.lang.IllegalStateException: Must be called from main thread of process
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1392)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
at android.support.v4.view.ViewPager.populate(ViewPager.java:804)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:344)
at com.servicemagic.pros.activities.LeadDetails.onCursorLoaded(LeadDetails.java:205)
at com.servicemagic.pros.activities.LeadDetails.access$200(LeadDetails.java:25)
at com.servicemagic.pros.activities.LeadDetails$QueryRunner.onPostExecute(LeadDetails.java:196)
at com.servicemagic.pros.activities.LeadDetails$QueryRunner.onPostExecute(LeadDetails.java:170)
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:150)
at android.os.HandlerThread.run(HandlerThread.java:60)

Итак - почему метод postExecute () не вызывается в MainThread?

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

Я полагаю, что @hovanessyan пытается понять, что небезопасно предполагать, что фрагмент, с которым говорил AsyncTask при запуске, может не совпадать с экземпляром, когда он завершает выполнение. Android может приостановить или даже остановить фрагмент, пока работает AsyncTask. Это объясняет, почему проблема носит прерывистый характер. Это происходит только с пользователями, когда их фрагмент приостановлен, уничтожен и воссоздан.

Эта проблема обсуждается в этой статье . Если вы прочитаете пункты 2 и 3 в статье, вы увидите, как их решить. Вы несете ответственность за сохранение и восстановление состояния как часть вашего жизненного цикла фрагмента. См. Документацию по Android для Жизненный цикл фрагмента .

2 голосов
/ 15 марта 2012

цикл onPause () - onResume () не проходит через onStart ().Если вам нужно, чтобы это было выполнено в начале вашей деятельности, поместите его в onResume ().Вы всегда проходите через onResume ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...