【问题标题】:Android -Retained headless fragmentAndroid - 保留的无头片段
【发布时间】:2016-07-25 05:56:49
【问题描述】:

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

本文有以下注释:

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

【问题讨论】:

    标签: java android android-fragments android-asynctask


    【解决方案1】:

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

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

    headlessFragment 的一个例子:

    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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      我通过检查调用片段或活动是否存在来简化我的情况的复杂性,只需更新您的 UI(如果必须)。通过分配调用实体的弱引用来启动异步任务。

      【讨论】:

        猜你喜欢
        • 2018-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-28
        • 2015-09-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多