如何找出saveInstance正在保存的数据

时间:2017-07-05 17:37:45

标签: android parcelable onsaveinstancestate android-binder

得到了android.os.TransactionTooLargeException,据说是因为

“当同时通过Parcel传输过多数据时会发生此异常。底层Binder事务缓冲区具有有限的固定大小,当前为1Mb,由进程正在进行的所有事务共享。因此,即使大多数单个事务的大小适中,当有许多事务正在进行时,也会抛出此异常。“

   android.os.TransactionTooLargeException: data parcel size 593484 bytes
   at android.os.BinderProxy.transactNative(Binder.java)
   at android.os.BinderProxy.transact(Binder.java:628)
   at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:4132)
   at android.app.ActivityThread$StopInfo.run(ActivityThread.java:4159)
   at android.os.Handler.handleCallback(Handler.java:751)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6692)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

在崩溃日志时显示mainActivity从onSaveInstanceState()开始,并且还包含一些片段。

  583   |   04:46:32:173 (UTC)  | MainActivity:onSaveInstanceState()
  584   |   04:46:32:174 (UTC)  | DataListFragment:onSaveInstanceState()
  585   |   04:46:32:174 (UTC)  | DrawerFragment:onSaveInstanceState()
  586   |   04:46:32:174 (UTC)  | DataContainerFragment:onSaveInstanceState()
  587   |   04:46:32:174 (UTC)  | DataDetailsFragment:onSaveInstanceState()
  588   |   04:46:32:175 (UTC)  | DataDetailsFragment:onSaveInstanceState()
  589   |   04:46:32:175 (UTC)  | DataDetailsFragment:onSaveInstanceState()

mainActivity有一个Drawer和一个列表片段,当点击列表项时,一个容器片段打开,它有一个viewPage并包含三个细节片段。

看起来积累的数据超过了Binder的1 meg限制。

在onSaveInstanceState()调用中仔细查看片段的所有已保存数据,它们都是小的(int,boolean等),所有在一起的时间都小于几k,比方说< 10K。

还查看了所有片段的布局文件,它们使用LiniearLayout,TextView,ImageView,WebView等。并做了一个日志来查看android View可能保存的数据。

日志显示所有这些片段的视图总共可以节省不到30k。

所以不知道这个“数据包大小593484字节”来自哪里。

或者必须有一些其他数据android系统也在保存(?)。

有没有办法找出或转储“底层Binder事务缓冲区”数据,看看它们可能来自哪些? 有谁知道Android为WebView说的数据是什么(或如何找到)?

===

扩展视图以执行日志,类似于片段中使用的其他视图

public class LogLinearLayout extends LinearLayout {

public LogLinearLayout(Context context) {
    super(context);
}

public LogLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public LogLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {

    super.dispatchSaveInstanceState(container);

    for (int i = 0; i < container.size()-1; i++) {
        Parcelable val = (Parcelable)container.get(i);

        byte[] bytes = val != null ? marshall(val) : null;
        String parcelByte = (bytes != null) ? "bytes.length:"+bytes.length : ("val==null");

        if(bytes != null) {
            //Log container level the bytes.length
        }

    }
}

@Override
protected Parcelable onSaveInstanceState() {
    Parcelable pVal = super.onSaveInstanceState();

    byte[] bytes = pVal != null ? marshall(pVal) : null;
    String parcelByte = (bytes != null) ? "bytes.length:"+bytes.length : ("val==null");

    if (bytes != null) {
        //Log the bytes.length of this view
    }

    return pVal;
}

byte[] marshall(Parcelable parceable) {
        Parcel parcel = Parcel.obtain();
        parceable.writeToParcel(parcel, 0);
        byte[] bytes = parcel.marshall();
        parcel.recycle();
        return bytes;
}

}

0 个答案:

没有答案