2015-06-22 3 views
1

Я испытываю эту проблему на некоторых устройствах, особенно в Samsung.Контексты и обратные вызовы от асинхронных задач

У меня есть деятельность, которая имеет 7 fragments. В большинстве из них я запускаю задачу async для получения некоторых данных. Я обрабатываю исключения, создавая обработчик в o nCreateView().

handler = new Handler(new Handler.Callback() { 
      @Override 
      public boolean handleMessage(Message msg) { 
       if (msg.what == 0) { 
        Toast.makeText(getActivity().getApplicationContext(), getActivity().getResources().getString(R.string.connection_timed_out), Toast.LENGTH_SHORT).show(); 
        return true; 
       } 
       return false; 
      } 
     }); 

При принятии API вызова, в catch блоках, если бывают исключения, я отменить async задачу и в onCancelled() обратного вызова, предупреждаю обработчик.

new AsyncTask<Void, Void, ArrayList<UserProfile>>() { 
      @Override 
      protected ArrayList<UserProfile> doInBackground(Void... params) { 
       try { 
      return new APIService().GetUserProfiles(EnloopApplication.getCurrent().getAuthenticationToken(), thisUserProfile.getEnloop_friends()); 
      } catch (WampNetworkException e) { 
       cancel(true); 
       e.printStackTrace(); 
      } catch (WampApiException e) { 
       e.printStackTrace(); 
      } catch (SocketTimeoutException e) { 
       cancel(true); 
      } 
      return null; 
     } 

     @Override 
     protected void onCancelled() { 
      super.onCancelled(); 
      handler.sendEmptyMessage(0); 
     } 

На большинстве устройств, она работает, но на Samsung устройств иногда я получаю null pointer exception поскольку getActivity() возвращает ничего, как будто activity был разрушен, и никогда не был создан заново. Проблема в том, что активность не разрушается в коде, поскольку происходит только то, что происходит между fragments в том же activity.

ответ

1

getActivity() возвращение null - вполне допустимый сценарий, который вы также должны ожидать.

Это происходит потому, что, создав в анонимную Handler ваш onCreateView вы ссылки Fragment, который уже был отделен от Activity (поэтому getActivity() возвращается null). То же самое касается вашего AsyncTask - если вы создаете его как анонимный класс внутри Fragment, тогда он также ссылается на тот же выделенный файл Fragment.

Я предлагаю вам пересмотреть свою архитектуру. Как? Я считаю, что ваши компоненты пользовательского интерфейса не должны выполнять асинхронные операции сами по себе. Вместо этого вы должны использовать какой-либо механизм публикации/подписки (есть решения, которые используют LoaderManager, HandlerThread, RxJava, RoboSpice и другие сторонние библиотеки).

+0

Спасибо :) Задумывался об использовании Retrofit, так как он содержит Rxjava – Alex

+1

@Alex, как вы можете себе представить, есть много способов избежать этого с их собственными преимуществами и недостатками. Лично я предпочитаю шаблон RxJava + MVP. Вы можете (лучше) Google это, есть много статей и примеров уже. –

+0

Прочитайте об этом :) Спасибо за полезную информацию – Alex

Смежные вопросы