You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API 28-32如何将InputQueue转换为AInputQueue?

问题:API 28-32 下 InputQueue 转 AInputQueue 的兼容方案

背景

自定义实现MyNativeActivity时需重写onInputQueueCreated()方法,原生NativeActivity的实现是调用InputQueue.getNativePtr()获取原生指针后传给onInputQueueCreatedNative():

public void onInputQueueCreated(InputQueue queue) {
    if (!mDestroyed) {
        mCurInputQueue = queue;
        onInputQueueCreatedNative(mNativeHandle, queue.getNativePtr());
    }
}

但存在版本兼容性问题:

  • API 28 及以下:getNativePtr()可通过JNI调用,但属于隐藏API
  • API 33 及以上:可使用NDK提供的AInputQueue_fromJava()直接转换
  • API 28-32:getNativePtr()被加入暗灰名单,调用返回null;反射调用该方法同样无效

可行解决方案

在API 28-32版本中,可通过反射直接读取InputQueue内部的mNativePtr字段(而非调用方法)获取原生指针:

反射获取原生指针代码

import java.lang.reflect.Field;

public static long getIQNativePtr(InputQueue queue) {
    try {
        // 反射读取InputQueue内部的mNativePtr字段
        Field field = InputQueue.class.getDeclaredField("mNativePtr");
        field.setAccessible(true);
        return (long) field.get(queue);
    } catch (Exception e) {
        e.printStackTrace();
        return 0;
    }
}

原理说明

API 28之后,InputQueue的getNativePtr()方法内部实际是返回mNativePtr字段,但该方法被标记为隐藏且加入暗灰名单,直接或反射调用都会被系统拦截;而直接反射读取mNativePtr字段,在多数设备上可绕过该限制(注意:字段名属于内部实现,部分定制ROM可能存在差异)。

全版本兼容处理

在onInputQueueCreated()中加入版本判断,覆盖所有API等级:

public void onInputQueueCreated(InputQueue queue) {
    if (!mDestroyed) {
        mCurInputQueue = queue;
        long nativePtr = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // API 33+ 使用NDK官方转换方法
            nativePtr = AInputQueue_fromJava(queue);
        } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
            // API 28及以下 直接调用getNativePtr()
            nativePtr = queue.getNativePtr();
        } else {
            // API 29-32 反射读取mNativePtr字段
            nativePtr = getIQNativePtr(queue);
        }
        if (nativePtr != 0) {
            onInputQueueCreatedNative(mNativeHandle, nativePtr);
        }
    }
}

注意事项

  • 反射访问内部字段存在兼容性风险,若厂商修改InputQueue内部实现,可能导致获取失败
  • 针对API 28-32,也可直接实现AInputQueue的JNI绑定逻辑,但复杂度较高,反射字段是更简便的临时方案

内容的提问来源于stack exchange,提问作者dawnmenu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 02:09:58