1

Привет, я думаю о том, что является правильным и лучшим способом обработки Activity, Fragment, AsyncTask и DialogFragments вместе.OrientationChange Управлять обработкой, фрагментом, AsyncTask и DialogFragments?

  • Мое текущее состояние, что я начинаю Activity и заменить его ContentView с моим Fragment, в котором я получил EditText и один Button.

  • Нажатие на мой Button выполняет AsyncTasks, который запрашивает случайные вещи и занимает некоторое время. Между тем я показываю DialogFragment попрошайничеством за терпение.

  • Желаемое поведение таково, например. Я вращаю свой экран, мой DialogFragment продолжает отображаться на время моего AsyncTask. После этого я хочу показать простой тост, отображающий информацию, полученную от моего HttpRequest.

Компактный обзор о том, как я думал, что это будет работать:

  • BaseFragment сохраняет WeakReference к Activity он прикреплен к
  • AsyncTask держит WeakReference к Fragment который exectures его
  • AsyncTasksonPreExecute() показывает DialogFragment
  • AsyncTasksonPostExecute() dissmisses DialogFragment
  • BaseFragment держит DialogFragment

К сожалению, это не так, как она работает, на смену ориентации продолжает отображается мой DialogFragment и не тост не появляется. Что я делаю неправильно?

public class BaseFragment extends Fragment{ 
private static final String TAG = BaseFragment.class.getSimpleName(); 

protected WeakReference<AppCompatActivity> mActivity; 
private TemplateDialogFragment dialogFragment; 

public WeakReference<AppCompatActivity> getAppCompatActivity(){ return mActivity; } 

@Override 
public void onAttach(Context context) { 
    if(!(context instanceof AppCompatActivity)) { 
     throw new IllegalStateException(TAG + " is not attached to an AppCompatActivity."); 
    } 

    mActivity = new WeakReference<>((AppCompatActivity) context); 

    super.onAttach(context); 
} 

@Override 
public void onDetach() { 
    mActivity = null; 
    super.onDetach(); 
} 

@Override 
public void onStart() { 
    super.onStart(); 
    showContent(); 
} 

public void showContent(){ 

} 

public void showDialog(String title, String content){ 
    dialogFragment = new TemplateDialogFragment(); 

    Bundle bundle = new Bundle(); 
    bundle.putString(TemplateDialogFragment.DIALOG_TITLE, title); 
    bundle.putString(TemplateDialogFragment.DIALOG_MESSAGE, content); 

    dialogFragment.setArguments(bundle); 
    dialogFragment.show(getFragmentManager(), TemplateDialogFragment.FRAGMENT_TAG); 
} 

public void notifyTaskFinished(String result) { 
    dismissDialog(); 

    if(mActivity != null && !mActivity.get().isFinishing()) { 
     Toast.makeText(mActivity.get().getApplicationContext(), result, Toast.LENGTH_LONG).show(); 
    } 
} 

private void dismissDialog(){ 
    if(dialogFragment != null && dialogFragment.isAdded()) { 
     dialogFragment.dismissAllowingStateLoss(); 
    } 
} 

} 

...

public class TemplateFragment extends BaseFragment { 
private static final String TAG = TemplateFragment.class.getSimpleName(); 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.test_fragment, container, false); 
} 
@Override 
public void showContent() { 
    super.showContent(); 

    Button startTask = (Button) getAppCompatActivity().get().findViewById(R.id.button0); 
    final BaseFragment instance = this; 

    startTask.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      CustomAsyncTask task = new CustomAsyncTask(instance); 
      EditText input = (EditText) getAppCompatActivity().get().findViewById(R.id.text0); 
      task.execute(input.getText().toString()); 
     } 
    }); 
} 

private static class CustomAsyncTask extends AsyncTask<String, Void, String> { 
    WeakReference<BaseFragment> weakBaseFragmentReference; 

    private CustomAsyncTask(BaseFragment fragment) { 
     weakBaseFragmentReference = new WeakReference<>(fragment); 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     weakBaseFragmentReference.get().showDialog("Executing", "Working on the request..."); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     HttpURLConnection con = HttpUrlConnectionFactory.createUrlConnection("https://www.httpbin.org/bytes/" + (params[0] == null ? "1" : params[0])); 
     return HttpRequester.doGet(con).getResponseAsString(); 
    } 

    @Override 
    protected void onPostExecute(String response) { 
     super.onPostExecute(response); 
     if(weakBaseFragmentReference.get() == null) { 
      return; 
     } 
     weakBaseFragmentReference.get().notifyTaskFinished(response); 
    } 
} 

} 

* Edit:

После некоторого времени, исследуя эту тему, я уверен, что Service является лучшим решением для большинства моей области использования. Также я использовал AsyncTaskLoaders много, потому что есть плавный контроль жизненного цикла ....

+1

Я думаю, что ваше окончательное приложение будет использовать сервис. Потому что в будущем вы захотите подключиться к своему приложению, пока оно не будет работать, и в телефон будут добавлены интересные сообщения о состоянии. А сервис будет запускать асинтез. – danny117

ответ

1

Использовать индикатор выполнения вместо DialogFragment.

AsyncTask должен использоваться только для задач, занимающих довольно много секунд.

AsyncTask не относится к жизненному циклу деятельности и может привести к утечке памяти.

Проверьте gotchas.

Вы можете попробовать AsyncTaskLoader, чтобы выжить при изменении конфигурации.

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

  • Нет связанных вопросов^_^