对于 Activity 的 onSaveInstanceState 方法大家都不会陌生,当 Activity 在不正常销毁的情况下,就会调用 onSaveInstanceState 方法,并将 Activity 中需要保存的数据(比如 View 状态 或者我们自己的数据)保存到这个方法的参数 Bundle 中。
一、onSaveInstanceState 的数据
对于 Activity 的 onSaveInstanceState 方法大家都不会陌生,当 Activity 在不正常销毁的情况下,就会调用 onSaveInstanceState 方法,并将 Activity 中需要保存的数据(比如 View 状态 或者我们自己的数据)保存到这个方法的参数 Bundle 中。
但是在实际使用的时候你可能会发现当保存的数据过大的时候就会看到如下的 log 日志
javabinder !!! FAILED BINDER TRANSACTION !!!
甚至可能发生异常(在高版本下会抛出异常,低版本直接打印日志)
android.os.TransactionTooLargeException
上面的信息都是表示 Bundle 传输的数据过大,那么问题来了, onSaveInstanceState 中 Bundle 的数据是存放在哪里,为什么又限制?
Binder 传输缓冲区是一个限制的大小的区域,大小为 1MB,这块缓冲区用于所有进程间的通信,也就是 Binder 通信。这些传输包括 onSaveInstanceState , startActivity 和其他与系统的交互,当传输的数据超过这个大小的时候就会抛出异常。
特别是 onSaveInstanceState 方法,因其需要在 Activity 返回的时候提供数据,官网建议是数据大小不大于 50K。
在追 onSaveInstanceState 的方法源码的时候,想要找到关于 Binder 方面的内容,就顺着Activity 的方法追,很多人都是到 Application 的 接口中就迷路了.
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityS较好ped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}
其实这是一个错误的方向,其实只要想到 onSaveInstanceState 有点类似于 Activity 中其他生命周期的方法,就可以发现 onSaveInstanceState 最开始也是有 ActivityThread 做统一管理的,那么 onSaveInstanceState 的调用 也就和 ActivityThread 有关。
Bundle 的创建
在 ActivityThread 的源码中可以看到有这么个方法
private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
r.state = new Bundle();
r.state.setAllowFds(false);
if (r.isPersistable()) {
r.persistentState = new PersistableBundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
}
其中最后调用了 mInstrumentation.callActivityOnSaveInstanceState 那么就到 mInstrumentation 类中查找
public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,
PersistableBundle outPersistentState) {
activity.performSaveInstanceState(outState, outPersistentState);
}
这个方法中又调用了 activity.performSaveInstanceState 的方法
final void performSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
onSaveInstanceState(outState, outPersistentState);
saveManagedDialogs(outState);
storeHasCurrentPermissionRequest(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, “onSaveInstanceState ” + this + “: ” + outState +
“, ” + outPersistentState);
}
…
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
onSaveInstanceState(outState);
}
最后调用的是 Activity onSaveInstanceState 方法 ,显然 callCallActivityOnSaveInstanceState 的 r.state 就是 onSaveInstanceState 的方法的中的参数 Bundle .而 r 就是 ActivityThread 的内部类 ActivityClientRecord
static final class ActivityClientRecord {
IBinder token;
int ident;
Intent intent;
String referrer;
IVoiceInteractor voiceInteractor;
Bundle state; // 这个就是 r.state 也就是 onSaveInstanceState 的 Bundle
}
延伸阅读:
二、什么是Activity的生命周期
简单来说,Activity的生命周期是指一个Activity从其从创建到销毁的过程中会处于不同的状态,每个状态也有其对应的回调方法,这些回调会让 Activity 知晓某个状态已经更改:系统正在创建、停止或恢复某个 Activity,或者正在销毁该 Activity 所在的进程。