gpt4 book ai didi

Android RemoteExceptions 和服务

转载 作者:IT老高 更新时间:2023-10-28 22:16:09 24 4
gpt4 key购买 nike

所以我为 Android 操作系统编写了一个服务和一个 Activity 。

我的服务在它自己的进程中运行,所以我的 Activity 和服务之间的所有通信都是通过 IPC 进行的。为此,我使用标准的 Android .aidl 机制。

到目前为止一切正常。但是,AIDL 使用“throws RemoteException”生成所有方法 stub ,所以我必须处理它们。

我对整个 Android 源代码进行了一次快速 grep,只发现了三个抛出此异常的情况。这些在我没有连接的不同服务中。

我也检查了 C 源代码,因为理论上 RemoteExceptions 可以使用 JNI 接口(interface)生成。没有任何结果。

我的印象是每个人都只是这样处理它们:

  try {

mService.someMethodCall (someArguments);

} catch (RemoteException e) {

e.printStackTrace();

}

这不是可靠的代码,我不希望在我的代码库中出现这样的内容。

除此之外:我自己尝试通过 IPC 抛出 RemoteException,我得到的只是堆栈跟踪和系统日志消息,告诉我尚不支持异常。我的应用程序从未见过异常,并且引发异常的服务最终处于非常奇怪的状态(中途工作):-(

问题是:

  • 这些异常会被抛出吗?

  • 有没有人见过这种捕获 RemoteException 的 try-catch block ?

  • 难道它们不存在,而我们只是被迫处理它们,因为“抛出 RemoteException”是死代码或 AIDL 编译器内的遗留代码?

Disclamer:我还没有阅读完整的源代码。我使用 Grep 来查找 RemoteException 的出现,所以我可能由于不同的空白使用而错过了一些。

最佳答案

确实会抛出这些异常,您应该编写适当的 try/catch 逻辑来处理您在服务上调用的远程方法未完成的情况。

就您的调查而言,您在查看本地资源时走在了正确的轨道上。你可能忽略了android.os.RemoteException实际上只是其他 Binder 相关异常的基类,它是子类 android.os.DeadObjectException ,在 native code of Binder 中抛出.

如果一个 Activity 使用了在另一个进程中运行的服务,而该服务在执行请求的过程中死掉了,它就会看到这个异常。通过对 Marko Gargenta's AIDLDemo example 进行以下小改动,我能够向自己证明这一点。 .

首先,通过更新 AndroidManifest.xml 确保服务在自己的进程中运行:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.marakana" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:theme="@android:style/Theme.Light">
<activity android:name=".AIDLDemo" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--ADD THE android:process TAG TO THE SERVICE-->
<service android:name=".AdditionService" android:process=":process2"/>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>

然后修改add方法提前退出:

@Override
public IBinder onBind(Intent intent) {

return new IAdditionService.Stub() {
/**
* Implementation of the add() method
*/
public int add(int value1, int value2) throws RemoteException {
Log.d(TAG, String.format("AdditionService.add(%d, %d)", value1,
value2));

System.exit(-1); // KILL THE PROCESS BEFORE IT CAN RESPOND

return value1 + value2;
}

};
}

在 logcat 中你会看到服务进程死亡,activity 收到 DeadObjectException,最终系统重新生成服务进程。

D/AdditionService( 1379): AdditionService.add(1, 1)
I/AndroidRuntime( 1379): AndroidRuntime onExit calling exit(-1)
D/Zygote ( 32): Process 1379 exited cleanly (255)
I/ActivityManager( 58): Process com.marakana:process2 (pid 1379) has died.
W/ActivityManager( 58): Scheduling restart of crashed service com.marakana/.AdditionService in 5000ms
D/AIDLDemo( 1372): onClick failed with: android.os.DeadObjectException
W/System.err( 1372): android.os.DeadObjectException
W/System.err( 1372): at android.os.BinderProxy.transact(Native Method)
W/System.err( 1372): at com.marakana.IAdditionService$Stub$Proxy.add(IAdditionService.java:95)
W/System.err( 1372): at com.marakana.AIDLDemo$1.onClick(AIDLDemo.java:81)
W/System.err( 1372): at android.view.View.performClick(View.java:2408)
W/System.err( 1372): at android.view.View$PerformClick.run(View.java:8816)
W/System.err( 1372): at android.os.Handler.handleCallback(Handler.java:587)
W/System.err( 1372): at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err( 1372): at android.os.Looper.loop(Looper.java:123)
W/System.err( 1372): at android.app.ActivityThread.main(ActivityThread.java:4627)
W/System.err( 1372): at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err( 1372): at java.lang.reflect.Method.invoke(Method.java:521)
W/System.err( 1372): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
W/System.err( 1372): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
W/System.err( 1372): at dalvik.system.NativeStart.main(Native Method)
D/AIDLDemo( 1372): onServiceDisconnected() disconnected
I/ActivityManager( 58): Start proc com.marakana:process2 for service com.marakana/.AdditionService: pid=1399 uid=10037 gids={1015}
D/AdditionService( 1399): onCreate()
D/AIDLDemo( 1372): onServiceConnected() connected

我想如果您的服务与您的 Activity 在同一进程中运行,您可能永远不会看到此异常,但如果是这种情况,您可能不会再为 AIDL 烦恼。

此外,正如您所发现的,Android 不会在进程之间建立异常 channel 。如果您需要将错误传达回调用 Activity ,那么您需要使用其他方式。

关于Android RemoteExceptions 和服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3156389/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com