Activity和Fragment并发

时间:2014-09-12 08:16:05

标签: java android android-fragments concurrency android-asynctask

根据Api活动和片段工作在同一个ui线程上。以下两个算法(伪代码)中是否存在并发问题?

  1. Activity在onCreate中启动一个片段并初始化一个可从片段访问的对象。

    //Object
    class Object{
         String name = "test";
         int age = 20;
    }
    
    //Activity onCreate
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startFragment();
        setActivityObject();
    }
    
    //Fragment onCreateView
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    
    getActivityObject();
    return view;
    

    }

  2. 根据android developers onCreateView可以在Activity完成onCreate之前完成(这就是我们调用onActivityCreated的原因)。 1)片段是否有可能在Activity初始化之前显示对象? 2)是否有可能,Activity将名称编辑为test2,然后在将年龄编辑为age = 10之前调用getActivityObject()片段然后片段将获得一个名为=" test2&#34的无效状态对象;和年龄= 20,而不是名称=" test2"年龄= 10岁。这种情况需要同步的setter / getter吗?

    1. 在上面的示例中,活动通过asyncTask设置对象。前两个场景是否存在同样的问题?
    2. 我已从我的项目中隔离了这个场景。在其他一些情况下,我使用回调来通知片段数据状态。我无法在此处使用它,因为Activity会替换片段,因此片段可能会在onCreateView中准备好数据,并且活动在这种情况下永远不会触发回调。

1 个答案:

答案 0 :(得分:4)

在考虑场景中的同步时,您需要区分线程同步,而不是简单地理解回调的顺序。只要您不使用线程,异步任务,计时器等 - 您就没有线程问题。但你仍然需要知道什么时候避免出现问题。

假设片段是Activity的xml布局的一部分,那么在 Activity的onCreate()方法完成之前,该片段的onCreateView()将被称为。这只是因为初始化片段的代码(因此最终调用片段'onCreateView())是活动的setContentView()方法的一部分,该方法在onCreate()中调用。在这些方法的开头和结尾都可以很容易地看到日志。你得到这样的东西:

Activity.onCreate start
Activity calling setContentView...
Fragment.onCreateView start
Fragment.onCreateView end
Activity setContentView done
Activity.onCreate end

订购是不变的并且有保证。换句话说,如果在活动的onCreate()方法中初始化对象,但在调用setContentView()之前,则片段可以自由地访问该对象。您对于不一致的对象状态也是100%安全的,因为所有这些回调确实在同一个线程上运行。根本不存在活动和片段同时处理对象的风险。

关于你的第二个问题 - 一旦你使用不同的线程初始化对象,你就不能再保证任何东西了。您无法判断初始化是否已完成。然后你需要开始考虑并发 - 同步你的getter / setter,使用回调来在片段完成时通知它,等等。