对上一篇的proxy模式中提到的例子进行优化如下:
package com.sean.mp3player;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
public interface IPlayer1 {
public void play();
public void stop();
public void getStatus();
public static abstract class Stub extends Binder implements IPlayer1 {
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
// TODO Auto-generated method stub
if (code == 1) {
this.play();
} else if (code == 2) {
this.stop();
} else if (code == 3) {
this.getStatus();
}
return true;
}
public abstract void play();
public abstract void stop();
public abstract void getStatus();
public static IPlayer1 asInterface(IBinder binder) {
return new Proxy(binder);//从Stub中生成Proxy的实例,更加说明了二者的密切联系。
}
private static class Proxy implements IPlayer1 {
private IBinder binder;
Proxy(IBinder binder) {
this.binder = binder;
}
@Override
public void play() {
// TODO Auto-generated method stub
try {
binder.transact(1, null, null, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void stop() {
// TODO Auto-generated method stub
try {
binder.transact(2, null, null, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void getStatus() {
// TODO Auto-generated method stub
try {
binder.transact(3, null, null, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
package com.sean.mp3player;
import android.content.Context;
public class Mp3Binder extends IPlayer1.Stub {
private Context context;
public Mp3Binder(Context context){
this.context = context;
}
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("---play---");
}
@Override
public void stop() {
// TODO Auto-generated method stub
System.out.println("---stop---");
}
@Override
public void getStatus() {
// TODO Auto-generated method stub
System.out.println("---getStatus---");
}
}
对比优化之前的例子,似乎只是把Proxy中的代码和Adapter中的代码移到了IPlayer接口的内部而已,但这个改动意义重大,首先从逻辑意义上来说,具有统一性的代码放置到了一起,更重要的在于隐藏了Stub(Binder)中的这个onTransact()实现,也就是说即使我们不懂跨进程调用也可以使用这个调用。