-1

最近,我观察到在使用 Android P 开发者预览版时,我维护的一个应用程序出现了大量崩溃。

潜入(深入)项目代码,我发现问题方法如下:

public static <T> T get(MatrixCursor cursor, int column) {
    try {
        cursor.moveToFirst();
        Method get = MatrixCursor.class.getDeclaredMethod("get", int.class);
        get.setAccessible(true);
        return (T) get.invoke(cursor, column);
    } catch (Exception e) {
        throw new IllegalArgumentException("Android has changed the implementation of MatrixCursor?!");
    }
}

据我了解,此代码用于直接从 MatrixCursor 中检索自定义对象,而不是原始类型、字节数组或字符串。以前有一个私有方法MatrixCursor内部执行此操作,我们通过反射访问此方法。

不用说,这种方法存在许多问题。据我所知,访问私有 API 的反射是 Android强烈反对的一项功能。尽管如此,在 Android P 预览版之前,这似乎一直在按预期工作。

这导致我提出以下问题:

的实现是否已MatrixCursor更改或从 Android P 开始完全弃用反射?

可悲的是,我不是 100% 知道我必须使用哪些替代方法来避免这个问题。非常感谢任何建议,是否有可用于存储自定义对象的光标?

4

1 回答 1

1

是的,有些事情发生了变化。

不,底层实现MatrixCursor可能没有改变。

改变的是Android P 引入了对 SDK 类的非公共成员的限制。尝试在 SDK 类上使用私有字段或方法(无论是通过直接调用、反射还是 JNI)将导致崩溃。

如果您在运行 P 的设备上运行相关代码并查看 logcat 输出,您应该会看到类似于以下内容的消息:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

我强烈建议您完整阅读有关这些限制的链接文档以获取完整的上下文以及有关如何处理它的更多信息。

一个选项(如果需要,您应该尽快这样做!)是提交错误,以便 Android 团队知道这是您使用的一种方法,并且没有公共替代方法。如果您在 Android P 发布之前执行此操作,则团队更有可能为此方法创建一个公共替代方案,或者允许您继续在 P 中访问该方法。

于 2018-05-31T15:06:17.397 回答