Open zengjingfang opened 6 years ago
BroadcastReceiver的onReceive()方法执行完成后,BroadcastReceiver的实例就会被销毁。如果onReceive()方法在10s内没有执行完毕,Android会认为改程序无响应。所以在BroadcastReceiver里不能做一些比较耗时的操作,否则会弹出“Application NoResponse”对话框。
这里不能使用子线程来解决 ,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。BroadcastReceiver一旦结束,此时它所在的进程很容易在系统需要内存时被优先杀死,因为它属于空进程。 【内容来自Broadcast Receiver开启服务而不是子线程处理耗时操作】
根据提供的参考链接,找到原文:
Furthermore, if the broadcast is an ordered broadcast then a malicious app could register itself with a high priority so as to receive the broadcast first. Then, it could either cancel the broadcast preventing it from being propagated further, thereby causing a denial of service, or it could inject a malicious data result into the broadcast that is ultimately returned to the sender.
Therefore, receivers of broadcast intents should be restricted. One way to restrict receivers is to use an explicit intent. An explicit intent can specify a component (using setComponent(ComponentName)) or a class (using setClass(Context, Class)) so that only the specified component or class can resolve the intent.
It is also possible to restrict the receivers of intents by using permissions, as described below. Alternatively, starting with the Android version ICE_CREAM_SANDWICH (Android API version 4.0), you can also safely restrict the broadcast to a single application by using Intent.setPackage().
Yet another approach is to use the LocalBroadcastManager class. Using this class, the intent broadcast never goes outside of the current process. According to the Android API Reference, LocalBroadcastManager has a number of advantages over Context.sendBroadcast(Intent):
1、Activity#onSaveInstanceState() 什么时候调用
通过源码追踪:
Instrumentation#callActivityOnSaveInstanceState
ActivityThread#callCallActivityOnSaveInstanceState(ActivityClientRecord r)
查到源头,真正触发的有三处:
ActivityThread#performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown, boolean saveState)
ActivityThread#handleRelaunchActivity(ActivityClientRecord tmp)
由源码可知,Activity#onSaveInstanceState()在三种情况下会被回调
在上述情况中,如果满足条件则回调callCallActivityOnSaveInstanceState
实际使用场景会被回调的情况如下
总之,就是你的操作并不确定要销毁当前的activity,但是由于系统的机制比如回收掉当前的activity,当再次恢复时就可能存在无法正常恢复的风险。通过在OnSaveInstanceState回调中保存临时数据,这样呢在恢复时会走onCreate(Bundle savedInstanceState),把临时保存的数据拿出来。如果你是非常确定要退出当前的activity,比如按下back键,那就不会回调OnSaveInstanceState。
还需要知道的是,系统默认实现了部分activity中的某些状态数据,比如UI控件的状态,比如EditText控件会自动保存和恢复输入的数据,前提是有为这个控件制定唯一的id,即android:id;
参考链接: