安卓TabLayout低版本的兼容性大坑

前段时间我尝试了把可可拼音输入法移植到9键手机上,比如多亲的F22以及日本一些像各种Softbank定制机,最低版本降至安卓5.0版本,除了按键的适配运行方面没有太大问题,后来我在自己的电子纸书上跑了一下,也还不错,具体见可可拼音输入法在QUADERNO上体验

中秋节回家给外婆的电视装上了我最近刚更新的可可桌面版本,但是发现无法切换默认桌面,系统做了修改,也就是我做的一键启动没法用,估计跟小米的差不多,本来我是想禁用系统桌面的,但是想了一下还是算了了,毕竟这不是测试设备,所以还是想通过输入法来实现这个一键启动应用的功能,因为很多机顶盒还是4.4版本的,我尝试把可可拼音输入法最低版本降低到安卓4.4进行测试,但是运行之后发现编辑框一旦激活输入法前台应用整个僵死,跟踪了一下发现是我在软件的符号面板上用到了控件com.google.android.material.tabs.TabLayout,会直接报错The style on this component requires your app theme to be Theme.AppCompat,但是在设置界面使用这个控件是正常的,于是我跟踪了一下,发现是ThemeEnforcment.java在检查上下文主题的时候报错,由于Activity是继承ContentThemeWrapper,没有问题,但是输入法创建的Candidates视图上下文是InputMethodService,理论上来说它应该使用Application的主题配置,不应该出现这个问题,但是事与愿违,Google的人在开发TabLayout组件的时候应该没有对低版本的系统进行过兼容测试,本来我还想通过反射修改一些属性来解决这个问题,但是跟到Resources.javaobtainStyledAttributes发现问题最终指向了AssetManagerapplyStyle,这个是调用native层的方法,没什么戏了。

// ThemeEnforcment.java
private static void checkTheme(
    @NonNull Context context, @NonNull int[] themeAttributes, String themeName) {
    if (!isTheme(context, themeAttributes)) {
        throw new IllegalArgumentException(
            "The style on this component requires your app theme to be "
            + themeName
            + " (or a descendant).");
    }
}
// Context.java
public final TypedArray obtainStyledAttributes(
    int resid, int[] attrs) throws Resources.NotFoundException {
    return getTheme().obtainStyledAttributes(resid, attrs);
}

// Resouces.java
public TypedArray obtainStyledAttributes(int[] attrs) {
    int len = attrs.length;
    TypedArray array = getCachedStyledAttributes(len);
    array.mRsrcs = attrs;
    AssetManager.applyStyle(mTheme, 0, 0, 0, attrs,
                            array.mData, array.mIndices);
    return array;
}

解决办法只能是换控件,目前我不想动这一块了,先放弃4.4版本支持了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

 桂ICP备15001694号-3