欢迎光临
我们一直在努力

Android 多进程开发 - 客户端 DeadObjectException 观察记录、通过 onCreate 验证、客户端死亡回调

一、客户端 DeadObjectException 概述

  • 如果客户端意外结束,服务端此时尝试回调客户端,会抛出 DeadObjectException 异常

二、客户端 DeadObjectException 观察记录

1、Callback
  • IPlayerCallback.aidl,这里是位于 src/main/java/com/my/common 包下

package com.my.common;

interface IPlayerCallback {
void onSongChanged(String songName);
void onPlayStateChanged(boolean isPlaying);
}

2、AIDL
  • IMyAidlInterface.aidl,这里是位于 src/main/java/com/my/common 包下

package com.my.common;

import com.my.common.IPlayerCallback;

interface IMyAidlInterface {
void play();
void pause();
void registerCallback(IPlayerCallback callback);
void unregisterCallback();
}

3、Server

private IPlayerCallback callback;
private String songName;
private boolean isPlaying = false;

private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

@Override
public void play() throws RemoteException {
if (isPlaying) {
Log.i(TAG, "play: already playing");
return;
}
isPlaying = true;

if (callback == null) {
Log.i(TAG, "play: callback is null");
return;
}

callback.onPlayStateChanged(isPlaying);

if (songName == null) {
songName = "Server Song";
callback.onSongChanged(songName);
}
}

@Override
public void pause() throws RemoteException {
if (!isPlaying) {
Log.i(TAG, "pause: not playing");
return;
}
isPlaying = false;

if (callback == null) {
Log.i(TAG, "pause: callback is null");
return;
}

callback.onPlayStateChanged(isPlaying);
}

@Override
public void registerCallback(IPlayerCallback callback) throws RemoteException {
ServerService.this.callback = callback;
}

@Override
public void unregisterCallback() throws RemoteException {
ServerService.this.callback = null;
}
};

  • play
  • try {
    myAidlInterface.play();
    } catch (RemoteException e) {
    e.printStackTrace();
    }

  • pause
  • try {
    myAidlInterface.pause();
    } catch (RemoteException e) {
    e.printStackTrace();
    }

    4、Client
  • play
  • try {
    myAidlInterface.play();
    Log.i(TAG, "play method success");
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "play method error: " + e.getMessage());
    }

  • pause
  • try {
    myAidlInterface.pause();
    Log.i(TAG, "pause method success");
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "pause method error: " + e.getMessage());
    }

  • registerCallback
  • try {
    myAidlInterface.registerCallback(new IPlayerCallback.Stub() {
    @Override
    public void onSongChanged(String songName) throws RemoteException {
    Log.i(TAG, "now thread: " + Thread.currentThread().getName());
    Log.i(TAG, "onSongChanged: " + songName);
    }

    @Override
    public void onPlayStateChanged(boolean isPlaying) throws RemoteException {
    Log.i(TAG, "now thread: " + Thread.currentThread().getName());
    Log.i(TAG, "onPlayStateChanged: " + isPlaying);
    }
    });
    Log.i(TAG, "registerCallback method success");
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "registerCallback method error: " + e.getMessage());
    }

  • unregisterCallback
  • try {
    myAidlInterface.unregisterCallback();
    Log.i(TAG, "unregisterCallback method success");
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "unregisterCallback method error: " + e.getMessage());
    }

    5、Test
    (1)Test 1
  • Client:调用 bindService,输出结果如下
  • 服务连接成功

  • Client:调用 registerCallback,输出结果如下
  • registerCallback method success

  • Client:调用 play,输出结果如下
  • now thread: main
    onPlayStateChanged: true
    now thread: main
    onSongChanged: Server Song
    play method success

  • Server:调用 bindService,输出结果如下
  • 服务连接成功

  • Server:调用 pause,输出结果如下
  • onPlayStateChanged: false

  • 结束 Client

  • Server:调用 play,输出结果如下

  • android.os.DeadObjectException

    (2)Test 2
  • Client:调用 bindService,输出结果如下
  • 服务连接成功

  • Client:调用 registerCallback,输出结果如下
  • registerCallback method success

  • Client:调用 play,输出结果如下
  • now thread: main
    onPlayStateChanged: true
    now thread: main
    onSongChanged: Server Song
    play method success

  • 结束 Client

  • Server:调用 bindService,输出结果如下

  • 服务连接成功

  • Server:调用 pause,输出结果如下
  • pause: not playing

  • Server:调用 play,输出结果如下
  • play: callback is null

    6、小结

    Test 1 测试小结:如果客户端意外结束,服务端此时尝试回调客户端,会抛出 DeadObjectException 异常

    Test 2 测试小结:出现了两个不同的 Service 实例


    三、通过 onCreate 验证

    1、Server

    @Override
    public void onCreate() {
    super.onCreate();

    Log.i(TAG, "onCreate: " + this);
    }

    2、Test
    (1)Test 1
  • Client:调用 bindService,输出结果如下
  • onCreate: com.my.server.service.ServerService@e3e25df

    服务连接成功

  • Client:调用 registerCallback,输出结果如下
  • registerCallback method success

  • Client:调用 play,输出结果如下
  • now thread: main
    onPlayStateChanged: true
    now thread: main
    onSongChanged: Server Song
    play method success

  • Server:调用 bindService,输出结果如下
  • 服务连接成功

  • Server:调用 pause,输出结果如下
  • onPlayStateChanged: false

  • 结束 Client

  • Server:调用 play,输出结果如下

  • android.os.DeadObjectException

    (2)Test 2
  • Client:调用 bindService,输出结果如下
  • onCreate: com.my.server.service.ServerService@7e74c7e

    服务连接成功

  • Client:调用 registerCallback,输出结果如下
  • registerCallback method success

  • Client:调用 play,输出结果如下
  • now thread: main
    onPlayStateChanged: true
    now thread: main
    onSongChanged: Server Song
    play method success

  • 结束 Client

  • Server:调用 bindService,输出结果如下

  • onCreate: com.my.server.service.ServerService@c2244cf

    服务连接成功

  • Server:调用 pause,输出结果如下
  • pause: not playing

  • Server:调用 play,输出结果如下
  • play: callback is null


    四、客户端死亡回调

    1、基本介绍
  • 在注册客户端回调时,可以获取客户端的 Binder 对象,调用 Binder 对象的 linkToDeath 方法,注册死亡回调,监听客户端是否挂了

  • 当客户端挂了,服务端会收到 binderDied 回调,调用 Binder 对象的 unlinkToDeath 方法,注销死亡回调,同时,将客户端回调设置为 null

  • 2、演示
    (1)Server

    @Override
    public void registerCallback(IPlayerCallback callback) throws RemoteException {
    ServerService.this.callback = callback;

    IBinder b = callback.asBinder();

    IBinder.DeathRecipient dr = new DeathRecipient() {

    @Override
    public void binderDied() {
    Log.i(TAG, "binderDied");
    b.unlinkToDeath(this, 0);
    ServerService.this.callback = null;
    }
    };

    b.linkToDeath(dr, 0);
    }

    (2)Test
  • Client:调用 bindService,输出结果如下
  • 服务连接成功

  • Client:调用 registerCallback,输出结果如下
  • registerCallback method success

  • Client:调用 play,输出结果如下
  • now thread: main
    onPlayStateChanged: true
    now thread: main
    onSongChanged: Server Song
    play method success

  • Server:调用 bindService,输出结果如下
  • 服务连接成功

  • Server:调用 pause,输出结果如下
  • onPlayStateChanged: false

  • 结束 Client
  • binderDied

  • Server:调用 play,输出结果如下
  • play: callback is null

    赞(0)
    未经允许不得转载:171主机测评 » Android 多进程开发 - 客户端 DeadObjectException 观察记录、通过 onCreate 验证、客户端死亡回调
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址