2016-03-06 67 views
0

我在调查活动切换生命周期方面做了一些实验,发现有一种情况会出现“黑屏”。如果我错了,请纠正我。在Android中,可能会出现黑屏作为开关活动

两项活动一& B.启动到B从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 

下面是在我的活动代码中的& 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. 不要在Act B onResume & onFocus上做太多事情,否则用户会看到“黑屏”。
  2. 接着(1),在Act B“onStart”中执行。最好让用户感受到前面的步骤A所示的延迟,而不是看到“黑屏”的延迟。
  3. AsyncTask绝对是解决方案。向用户显示视图是重中之重,之后应用数据。

然而,还有一个场景是这样的:
图表应用。用户可以在Activity中看到“图表(布局)”,但最新的数据还没有被填充,因为第二个线程仍在提取数据(可能是因为它太重了)。

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


有没有人找到这个“黑屏”的陷阱?还是我错误地理解了事情?非常感谢你!

+0

你可以显示代码你有什么活动A和B –

回答

0

你绊倒在与Android基本原则之一:

不要做(太多)在主线程上运行。

主线程是你的UI线程。生命周期回调方法,如onCreate,onStart等都在主/ UI线程上调用。

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

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

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

5秒钟执行生命周期回调应该是而不是就是这样。使用在onCreate或其他适当的地方开始的装载机,并在完成后用数据填写您的意见。确保您了解何时调用每个生命周期回调,因为多次执行相同的操作(例如onResume)也可能会浪费精力。

0

在上面的所有代码中添加睡眠将挂起主线程(这是ui线程) - 这可以解释奇怪的黑屏。如果那里没有睡觉怎么办?我认为你仍然可以通过日志了解生命周期,但没有任何睡眠。我知道你在做一个模拟,但是如果你的实际任务要花费很长时间,那就去探索一下多线程方法吧(关键词:Looper,AsyncTask,Thread,Runnable,Message,Queue,Post,Handlers等等...这是一个复杂的话题)。

相关问题