Android Things远程服务调用PeripheralManager.getInstance抛Stub!异常求助
解决Android Things远程服务中PeripheralManager抛出Stub!异常的问题
这个RuntimeException: Stub!异常其实是个很典型的信号——你的远程服务所在的独立进程没办法访问到Android Things外设API的真实实现,原因和Android Things的外设访问机制有关,咱们一步步来解决:
核心问题原因
Android Things的Peripheral I/O API(包括PeripheralManager)是进程绑定的系统服务,并且系统限制了只有应用的主进程(或者与主进程同进程的组件)才能获取到它的真实实现。当你把服务配置为独立进程(android:process=":remote")时,这个进程的类加载环境里只有API的存根(Stub)代码,没有真正的系统服务绑定逻辑,所以调用getInstance()时就会抛出这个异常。
另外要明确:Android Things不支持跨进程直接访问外设硬件,所有外设操作必须在应用的主进程中完成。
直接解决方案
修改你的Manifest文件,移除服务的独立进程配置,让服务和主进程运行在同一个进程中:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.afollestad.remotedemo"> <uses-permission android:name="com.google.android.things.permission.USE_PERIPHERAL_IO" /> <application> <!-- 移除android:process=":remote"配置,让服务运行在主进程 --> <service android:name=".RemoteService"> <intent-filter> <action android:name="service.remote" /> </intent-filter> </service> </application> </manifest>
修改后,服务和主进程共享同一个进程环境,就能正常获取到PeripheralManager的真实实现了。
如果你确实需要跨进程交互
如果业务场景必须用到跨进程通信,不要在独立进程的服务中直接操作外设,而是把外设操作逻辑封装在主进程的单例组件里,通过AIDL让远程进程调用主进程的方法来完成外设操作:
- 在主进程中创建一个单例类,负责管理
PeripheralManager和外设连接:
public class PeripheralHelper { private static PeripheralHelper instance; private PeripheralManager manager; private I2cDevice i2cDevice; private PeripheralHelper(Context context) { manager = PeripheralManager.getInstance(); // 这里初始化外设连接 } public static synchronized PeripheralHelper getInstance(Context context) { if (instance == null) { instance = new PeripheralHelper(context.getApplicationContext()); } return instance; } // 对外提供外设操作方法 public void testI2cConnection() throws IOException { // 你的I2C操作逻辑 } }
- 在你的RemoteService(即使保留独立进程)中,通过AIDL调用主进程的
PeripheralHelper方法(注意:这里需要通过跨进程通信传递操作请求,而不是在远程进程中直接创建外设实例)。
额外验证步骤
- 确认运行环境:确保你的应用是运行在真实的Android Things设备上,而不是普通Android模拟器——模拟器本身没有Android Things的外设服务,调用这些API也会触发Stub异常。
- 权限检查:虽然你已经声明了
USE_PERIPHERAL_IO权限,但可以在代码里主动验证权限是否被授予(Android Things 1.0及以上版本会自动授予这个权限,但如果是自定义系统可能需要确认)。 - 外设可用性:调用
manager.getI2cBusList()确认I2C1确实存在于你的设备上,避免因为外设名称错误导致后续的IOException。
内容的提问来源于stack exchange,提问作者Ting Yu Chen
相关产品推荐
相关产品推荐

