Android-遗留无头片段

我正在阅读有关如何在UI和后台线程之间进行交互的内容。

本文有以下注意事项:

AsyncTask不会自动处理配置更改,即重新创建活动。 程序员必须在编码中处理这个问题。 对此的常见解决方案是在保留的无头片段中声明AsyncTask。

我不明白什么是保留无头碎片。

例如,通过这种方式我可以添加片段:

FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.frame, new MyFragment()); transaction.commit(); 

在片段中我可以像这样执行AsyncTask:

 MyTask myTask = new MyTask(); String[] args = {"Hello"}; myTask.execute(args); 

这被称为“在保留的无头片段中声明AsyncTask”吗?

无头片段只不过是一个没有视图的片段。 在片段lifeCycle的onCreate()中,使用setRetainInstance(true); 。 即使活动重新创建,这也不会破坏片段。 因此,如果AsyncTask在片段中运行,则在重新创建活动时,您将不会丢失AsyncTask。

在活动的onCreate中,您必须添加带有标记的片段。 在添加之前,使用getFragmentManager().findFragmentByTag(TAG)检查片段是否存在,如果片段为null,则创建片段的新实例并添加它。 在Fragment中,不会有任何视图膨胀,因此不需要覆盖onCreateView()

headlessFragment的一个例子:

 public class HeadlessProgressFragment extends Fragment { private ProgressListener mProgressListener; private AsyncTask mProgressTask; public interface ProgressListener { void updateProgress(int progress); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); } public void setProgressListener(Context context) { mProgressListener = (ProgressListener) context; } public void startProgress(final int size) { if (mProgressTask == null || mProgressTask.getStatus() != AsyncTask.Status.RUNNING || mProgressTask.getStatus() == AsyncTask.Status.FINISHED) { mProgressTask = new AsyncTask() { @Override protected Void doInBackground(Void... params) { for (int index = 0; index < size; index++) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } finally { publishProgress(index + 1); } } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if (mProgressListener != null) { mProgressListener.updateProgress(values[0]); } } }; mProgressTask.execute(); } } } 

在活动中这样的事情:

 public class MainActivity extends FragmentActivity implements HeadlessProgressFragment.ProgressListener { private static final String TAG = "progress_fragment"; private ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dummy_view); mHeadlessProgressFragment = (HeadlessProgressFragment) getSupportFragmentManager().findFragmentByTag(TAG); if (mHeadlessProgressFragment == null) { mHeadlessProgressFragment = new HeadlessProgressFragment(); getSupportFragmentManager().beginTransaction().add(mHeadlessProgressFragment,TAG).commit(); } mHeadlessProgressFragment.setProgressListener(this); mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); final Button startFillBtn = (Button) findViewById(R.id.btn_start_filling); startFillBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mHeadlessProgressFragment.startProgress(100); } }); } @Override public void updateProgress(int progress) { mProgressBar.setProgress(progress); } } 

正如我通过检查调用片段或活动是否存在而更新您的UI(如果必须),简化了我的案例的复杂性。 通过分配调用实体的弱引用来启动asynctask。