在Android中,可能会出现黑屏作为切换活动

时间:2016-03-06 13:48:22

标签: android lifecycle

我做了一些关于调查活动切换生命周期的实验,发现有一种情况是黑屏"会发生。如果我错了,请好好纠正我。

两项活动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");
}

通过上述实验,我得出了一些结论和设计策略。

  1. 不要在关于Reses&amp ;;的行为B上做太多事情。 onFocus,否则用户将看到"黑屏"。
  2. 在(1)之后,按照行动B" onStart"相反。最好让用户感觉到延迟,因为之前的法案A显示的视图比看到"黑屏"。
  3. AsyncTask绝对是解决方案。向用户显示视图是最重要的,之后应用的数据。
  4. 然而,还有这样的场景:
    图表应用程序。用户可以看到"图表(布局)"在活动中,但最新的数据还没有填写,因为第二个线程仍在提取数据(可能是因为它太重了)。

    此时用户将看到一个空白图表。为避免这种情况,我们可以在创建Activity之前获取数据。在上一个Activity或Application的开头执行此操作。为了平滑用户体验。

    有没有人发现这个"黑屏"陷阱也是?或者我错误地理解了什么?非常感谢你!

2 个答案:

答案 0 :(得分:0)

你偶然发现了android的一个基本原则:

  

不要(太多)在主线程上工作。

主线程是你的UI线程。像onCreateonStart等生命周期回调方法都在主/ UI线程上调用。

如果你做了太多工作,你最终会看到屏幕冻结和/或黑屏,是的。

但这不应影响您创建视图或用数据填充视图的位置。这就是为什么有不同的生命周期方法。例如。 onCreate被调用一次,这就是为什么你应该在那里设置你的布局。每次用户切换回您的活动时,都会调用onResume。你应该在那里恢复动画。

AsyncTask确实是从主线程加载数据的好主意。如果您想要正确执行此操作,请同时查看LoaderManagerLoader

执行生命周期回调5秒应该。使用您在onCreate或其他适当位置开始的加载程序,并在完成后使用数据填充您的视图。确保您了解调用每个生命周期回调的时间,因为多次执行相同的操作(例如onResume)也可能浪费能源。

答案 1 :(得分:0)

在上面的所有代码中添加sleep会挂起主线程(这是ui线程) - 这可以解释奇怪的黑屏。如果那里没有睡觉怎么办?我想你仍然可以通过日志了解生命周期,但没有任何睡眠。

我知道您正在进行模拟,但如果您的实际任务需要花费很长时间,请尝试探索多线程方法(关键字:Looper,AsyncTask,Thread,Runnable,Message,Queue,Post,Handlers等) ......这是一个复杂的话题。)