根据Api活动和片段工作在同一个ui线程上。以下两个算法(伪代码)中是否存在并发问题?
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;
}
根据android developers onCreateView可以在Activity完成onCreate之前完成(这就是我们调用onActivityCreated的原因)。 1)片段是否有可能在Activity初始化之前显示对象? 2)是否有可能,Activity将名称编辑为test2,然后在将年龄编辑为age = 10之前调用getActivityObject()片段然后片段将获得一个名为=" test2&#34的无效状态对象;和年龄= 20,而不是名称=" test2"年龄= 10岁。这种情况需要同步的setter / getter吗?
我已从我的项目中隔离了这个场景。在其他一些情况下,我使用回调来通知片段数据状态。我无法在此处使用它,因为Activity会替换片段,因此片段可能会在onCreateView中准备好数据,并且活动在这种情况下永远不会触发回调。
答案 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,使用回调来在片段完成时通知它,等等。