1

嗨,我正在考虑什么是正确和最好的方式来处理ActivityFragmentAsyncTaskDialogFragments在一起。OrientationChange处理Activity,Fragment,AsyncTask和DialogFragments?

  • 我现在的状态是,我开始Activity和我Fragment,在我得到了一个EditText和一个Button替换其内容查看。

  • 点击我的Button执行一个AsyncTasks,它要求随机的东西,需要一些时间。同时我显示DialogFragment乞求耐心。

  • 期望的行为是,例如,我旋转我的屏幕我的DialogFragment一直显示我的AsyncTask正在运行的时间。之后,我想显示一个简单的吐司,显示我从HttpRequest得到的信息。

,我怎么觉得这是可行的紧凑概述:

  • BaseFragment保持一个WeakReference给它附加到
  • AsyncTaskActivity保持一个WeakReferenceFragment这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); 
    } 
} 

} 

*编辑:

一段时间后,研究这个主题,我敢肯定Service是我的大多数应用领域的最佳解决方案。我也用了很多AsyncTaskLoaders,因为有一个生命周期的光滑控制....

+1

我认为你的终极应用会使用一项服务。因为将来您会希望在未运行时连接到您的应用,并将冷却状态消息放入手机中。该服务将运行asynctask。 – danny117

回答

1

使用进度条代替DialogFragment。

AsyncTask只能用于需要几秒钟的任务。

AsyncTask不尊重Activity生命周期,并可能导致内存泄漏。

查看一些gotchas

你可以尝试AsyncTaskLoader生存配置更改。