且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Android的异常RemoteExceptions和服务

更新时间:2023-02-26 21:48:05

这些例外情况确实异常抛出,你应该写适当的try / catch逻辑来处理,即远程方法你调用一个服务都没有的情况完成了。

据你的调查,你是在正确的轨道翻翻本地源。你可能忽略的是,android.os.RemoteException$c$c>为其他粘合剂有关的异常一个实际上只是一个基类,它是一个子类,android.os.DeadObjectException$c$c>,这是在native活页夹的code。

As far as your investigation, you were on the right track looking through the native sources. What you may have overlooked is that android.os.RemoteException is a actually just a base class for other Binder related exceptions and that it is a subclass, android.os.DeadObjectException, which is thrown within the native code of Binder.

这是活动将看到这个异常,如果它使用了一个服务运行在另一个进程死亡在执行请求的中间。我能够证明这一点对自己通过以下小改动马尔科Gargenta的AIDLDemo例如

An activity will see this exception if it makes use of a service running in another process that dies in the middle of performing a request. I was able to prove this to myself by making the following minor changes to Marko Gargenta's AIDLDemo example.

首先,确保该服务通过更新的Andr​​oidManifest.xml运行在自己的进程:

First, make sure the service runs in its own process by updating the 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> 

然后修改添加方法来退出prematurely:

Then modify the add method to exit prematurely:

@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 ,最终实现系统重生的服务流程。

In logcat you see the service process die, the activity receive a DeadObjectException, and ultimately the system respawn the service process.

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困扰的情况下。

I would imagine if your service was running in the same process as your activity you might never see this exception but then again if that were the case you probably wouldn't be bothering with AIDL.

此外,当你发现了,Android的做进程之间没有隧道例外。如果您需要回去传达错误的呼叫活动,那么你需要使用其他手段。

Additionally, as you discovered, Android does not tunnel exceptions between processes. If you need to communicate an error back to a calling activity then you need to use other means.