我做了一些关于调查活动切换生命周期的实验,发现有一种情况是黑屏"会发生。如果我错了,请好好纠正我。
两项活动A& B.从A。发射到B。
03-06 13:04:52.811: I/LOG(32125): pause A begin
03-06 13:04:53.811: I/LOG(32125): pause A return
03-06 13:04:53.813: I/LOG(32125): focus A begin
03-06 13:04:58.813: I/LOG(32125): focus A return
In the window, shows the view of Activity A.
03-06 13:04:58.829: I/LOG(32125): create B begin
03-06 13:04:58.845: I/LOG(32125): create B return
03-06 13:04:58.846: I/LOG(32125): start B begin
03-06 13:04:59.847: I/LOG(32125): start B return
The view of Act A is hide, it is now shown by Activity B, but it's actually a "black screen" rather than the "actual genereated layout" in Activity B
03-06 13:04:59.847: I/LOG(32125): resume B begin
03-06 13:05:00.847: I/LOG(32125): resume B return
03-06 13:05:00.968: I/LOG(32125): focus B begin
03-06 13:05:05.968: I/LOG(32125): focus B return
Until this point, the "actual generated layout" of Activity B is shown here.
03-06 13:05:06.044: I/LOG(32125): A onSaveInstance
03-06 13:05:06.044: I/LOG(32125): stop A begin
03-06 13:05:07.044: I/LOG(32125): stop A return
以下是我的活动A& B.我使用Thread.sleep来模拟长期任务。 (也许这不适合进行模拟?)
@Override
protected void onStart() {
super.onStart();
Log.i("LOG","start B begin");
try {
Thread.sleep(5000,0);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("LOG","start B return");
}
@Override
protected void onResume() {
super.onResume();
Log.i("LOG","resume B begin");
try {
Thread.sleep(5000,0);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("LOG","resume B return");
}
@Override
protected void onStop() {
super.onStop();
Log.i("LOG","stop B begin");
try {
Thread.sleep(3000,0);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("LOG","stop B return");
}
@Override
protected void onPause() {
super.onPause();
Log.i("LOG", "pause B begin");
try {
Thread.sleep(3000,0);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("LOG","pause B return");
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.i("LOG","focus B begin");
try {
Thread.sleep(5000,0);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("LOG","focus B return");
}
通过上述实验,我得出了一些结论和设计策略。
然而,还有这样的场景:
图表应用程序。用户可以看到"图表(布局)"在活动中,但最新的数据还没有填写,因为第二个线程仍在提取数据(可能是因为它太重了)。
此时用户将看到一个空白图表。为避免这种情况,我们可以在创建Activity之前获取数据。在上一个Activity或Application的开头执行此操作。为了平滑用户体验。
有没有人发现这个"黑屏"陷阱也是?或者我错误地理解了什么?非常感谢你!
答案 0 :(得分:0)
你偶然发现了android的一个基本原则:
不要(太多)在主线程上工作。
主线程是你的UI线程。像onCreate
,onStart
等生命周期回调方法都在主/ UI线程上调用。
如果你做了太多工作,你最终会看到屏幕冻结和/或黑屏,是的。
但这不应影响您创建视图或用数据填充视图的位置。这就是为什么有不同的生命周期方法。例如。 onCreate
被调用一次,这就是为什么你应该在那里设置你的布局。每次用户切换回您的活动时,都会调用onResume
。你应该在那里恢复动画。
AsyncTask
确实是从主线程加载数据的好主意。如果您想要正确执行此操作,请同时查看LoaderManager
和Loader
。
执行生命周期回调5秒应该不。使用您在onCreate
或其他适当位置开始的加载程序,并在完成后使用数据填充您的视图。确保您了解调用每个生命周期回调的时间,因为多次执行相同的操作(例如onResume
)也可能浪费能源。
答案 1 :(得分:0)
在上面的所有代码中添加sleep会挂起主线程(这是ui线程) - 这可以解释奇怪的黑屏。如果那里没有睡觉怎么办?我想你仍然可以通过日志了解生命周期,但没有任何睡眠。
我知道您正在进行模拟,但如果您的实际任务需要花费很长时间,请尝试探索多线程方法(关键字:Looper,AsyncTask,Thread,Runnable,Message,Queue,Post,Handlers等) ......这是一个复杂的话题。)