提问者:小点点

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


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

两项活动A

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中的代码

@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. 不要在简历上做太多事情

但是,也有这样的场景:
一个图表应用程序。用户在活动中看到“图表(布局)”,但最新的数据还没有填写,因为第二个线程仍在获取数据(可能是因为它太重了)。

此时,用户将看到一个空白图表。为了避免这种情况,我们可以在创建活动之前获取数据。在上一个活动中或在应用程序开始时执行此操作。为了流畅的用户体验。

有没有人也发现这个“黑屏”陷阱?还是我理解错误?非常感谢!


共2个答案

匿名用户

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

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

主线程是UI线程。生命周期回调方法,如onCreateon Start等都在主/UI线程上调用。

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

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

AsyncTask确实是一个从主线程加载数据的好主意。如果你想正确地做到这一点,也可以看看LoaderManagerLoader

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

匿名用户

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

我知道您正在进行模拟,但如果您的实际任务需要那么长时间,请探索多线程方法(关键字:活套、异步任务、线程、可运行、消息、队列、帖子、处理程序等……这是一个复杂的主题)。