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"?

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

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

无头片段示例:

public class HeadlessProgressFragment extends Fragment {
private ProgressListener mProgressListener;
private AsyncTask<Void, Integer, Void> 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<Void, Integer, Void>() {
                @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(如果必须的话),简化了我的情况的复杂性。通过分配调用实体的weakreference来启动异步任务。

最新更新