Эти исключения действительно генерируются, и вы должны написать соответствующую логику try / catch для обработки ситуации, когда удаленный метод, который вы вызывали в службе, не завершился.
Что касается вашего расследования, вы были на правильном пути, просматривая родные источники. Возможно, вы упустили из виду, что android.os.RemoteException
на самом деле является просто базовым классом для других исключений, связанных с Binder, и что это подкласс android.os.DeadObjectException
, который выбрасывается в собственный код Binder .
Действие увидит это исключение, если оно использует службу, запущенную в другом процессе, который умирает в середине выполнения запроса. Я смог доказать это самому себе, внеся следующие незначительные изменения в пример AIDLDemo Марко Гаргенты .
Во-первых, убедитесь, что служба работает в своем собственном процессе, обновив 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 вы видите, что сервисный процесс умирает, действие получает 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
Я бы подумал, что если ваша служба работает в том же процессе, что и ваша деятельность, вы, возможно, никогда не увидите это исключение, но опять же, если бы это было так, вы, вероятно, не стали бы беспокоиться о AIDL.
Кроме того, как вы обнаружили, Android не туннелирует исключения между процессами. Если вам нужно сообщить об ошибке обратно вызывающей деятельности, вам нужно использовать другие средства.