androidX迁移问题记录

本文记录了项目,从support库,迁移到了最新的androidx库,迁移后一些兼容性问题处理。

迁移过程很顺利,后续自动化测试发现有两个问题,都是关于FloatingActionButton

1、崩溃 android.os.BadParcelableException: ClassNotFoundException when unmarshalling

复现条件:首页有FloatingActionButton,子页模拟app杀死重建。退出子页回到首页,崩溃。
原因:我们继承了FloatingActionButton,重写了保存恢复函数,在恢复的时候,ClassLoader为Null导致崩溃。
详细可以参考:https://wangchao.im/2016/10/12/android-badpracelableexception/

解决办法:使用系统提供的方法保存、恢复View的数据。

核心类
public class XLViewSavedStateHelper {

    private static final String BUNDLE_KEY = "XL_VIEW_BUNDLE_KEY";

    public static Bundle saveState(Parcelable parcelable) {
        if (parcelable == null) return null;

        if (parcelable instanceof Bundle) return (Bundle) parcelable;

        Bundle bundle = new Bundle();
        bundle.putParcelable(BUNDLE_KEY, parcelable);
        return bundle;
    }

    public static Parcelable getXLSaveParcelable(Parcelable state) {
        if (state instanceof Bundle) {
            return ((Bundle) state).getParcelable(BUNDLE_KEY);
        }
        return null;
    }

    public static boolean isXLSave(Parcelable parcelable) {
        return parcelable instanceof Bundle && ((Bundle) parcelable).getParcelable(BUNDLE_KEY) != null;
    }

}
使用方式
 private static final String KEY_PASSED_TIME = "KEY_PASSED_TIME";
    private static final String KEY_SYSTEM_CLOCK_TIME = "KEY_SYSTEM_CLOCK_TIME";

    @Override
    public Parcelable onSaveInstanceState() {
        Bundle bundle = XLViewSavedStateHelper.saveState(super.onSaveInstanceState());
        if (bundle != null) {
            bundle.putLong(KEY_PASSED_TIME, mPassedTime);
            bundle.putLong(KEY_SYSTEM_CLOCK_TIME, SystemClock.elapsedRealtime());
        }
        return bundle;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        if (!XLViewSavedStateHelper.isXLSave(state)) {
            super.onRestoreInstanceState(state);
            return;
        }

        super.onRestoreInstanceState(XLViewSavedStateHelper.getXLSaveParcelable(state));
        Bundle bundle = (Bundle) state;
        long passedTime = bundle.getLong(KEY_PASSED_TIME);
        long systemTime = bundle.getLong(KEY_SYSTEM_CLOCK_TIME);
        mPassedTime = passedTime + SystemClock.elapsedRealtime() - systemTime;
    }

2、同时操作FloatingActionButton,按钮图标丢失

复现条件:首页fab按钮,多个tab下的子页会去同时更新按钮状态,fab的图标丢失了。
原因:在androidX上出现,support库里的FloatingActionButton不会有这个问题。排查源码未找到原因
解决办法:限制更新频率,本质上来说,fab按钮只由当前页面来管理,其余不可见的页面,发出的更新请求应该被过滤掉。

观察了下很多更新请求,setImageResource()的操作都是同样的图片源,因此也可以简单粗暴的解决这个问题。

public class SafeFloatingActionButton extends FloatingActionButton {
    private Integer mPreviousRes;

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

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

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

    @Override
    public void setImageResource(int resId) {
        if (mPreviousRes != null && mPreviousRes == resId) return;

        mPreviousRes = resId;
        super.setImageResource(resId);
    }
}

总结

安卓因为历史原因,有supportV4、supportV7两大库,现在androidX可以终结掉这个分裂现象。官方提供的升级指引很简单方便,咱千万用户的app迁移下来很顺利,只发现这两处问题。

彩蛋

经过迁移后,项目里面搜.support.找到了android.support.FILE_PROVIDER_PATHS,这个7.0引入的FileProvider,路径就是这样的哦,设计如此。

    
            
        

你可能感兴趣的:(androidX迁移问题记录)