我正在尝试理解一段使用Android Binders和Messages来执行IPC的代码。我已经阅读了一些关于绑定器的文章,论文和幻灯片,但我仍然感到困惑并且很难理解代码,因为我没有遇到任何在java代码中实际实现绑定器的教程/示例。我列出了下面的清理/缩写代码,以及我对它的作用以及混淆程度的理解。如果有人能帮助我理解这一点,我将不胜感激,特别是有关包裹和信息的流动。
MyService.java
public class MyService extends Service
{
private final IMyService.Stub mBinder;
private Context _mContext;
private MyServiceHandler mHandler;
private HanderThread mHandlerThread;
private IHelperService mHelperService;
public MyService() {
this.mBinder = new IMyService.Stub() {
public void start_data(final String data) {
try {
if (MyService.this.mHelperService == null) {
return;
}
Message msg = MyService.this.getHandler().obtainMessage(3, (Object)data);
MyService.this.getHandler().sendMessage(msg);
} catch (SecurityException ex) {
// do some logging
}
};
}
private void startMessageProcess(final String message) {
// Process the message argument
final byte[] dataArray = this.getByteArray(message);
byte[] returnData;
try {
returnData = this.mHelperService.foo(dataArray);
} catch (Exception e) {
// do some logging
}
Message msg = this.getHandler().obtainMessage(3, (Object)message);
this.getHandler.sendMessage(msg);
}
private String getServerData(int id) {
// builds a Uri based on id and posts it, retrieves String data from HTTP entity and returns it
}
private boolean postDataToServer(final byte[] arrayData) {
// builds a Uri, post data to it, gets the status code, returns true if successful
}
private void sendData(final byte[] arrayData) {
final Intent intent = new Intent();
intent.setAction("com.my.service.intent.action.MY_RESULT");
intent.putExtra("com.my.service.intent.extra.RESULT", 0);
intent.putExtra("com.my.service.intent.extra.MY_DATA", arrayData);
this._mContext.sendBroadcast(intent, "com.my.service.permission.MY_PERMISSION");
}
public Handler getHandler() {
return this.mHandler;
}
public IBinder onBind(final Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (action != null && action.equals("com.my.service.intent.action.BIND_MY_SERVICE")) {
this._mContext = this.getApplicationContext();
return (IBinder)this.mBinder;
}
}
return null;
}
public void onCreate() {
super.onCreate();
try {
final Class<?> serviceManager = Class.forName("android.os.ServiceManager");
this.mHelperService = mHelperService.Stub.asInterface((IBinder)serviceManager.getMethod("getService", String.class).invoke(serviceManager, "helperservice"));
if (this.mHelperService == null) {
return;
}
}
catch (ClassNotFoundException ex2) {
Log.e("MyService", "Helper service ClassNotFoundException !!!");
}
catch (Exception ex) {
Log.e("MyService", "onCreate() Exception: " + Log.getStackTraceString((Throwable)ex));
}
this.mHandlerThread = new HandlerThread("MyService");
this.mHandlerThread.start();
this.mHandler = new MyServiceHandler(this.mHandlerThread.getLooper());
}
public int onStartCommand(final Intent intent, final int flags, final int startId) {
if (intent != null) {
super.onStartCommand(intent, flags, startId);
}
return START_NOT_STICKY;
}
private final class MyService Handler extends Handler
{
public MyServiceHandler(final Looper looper) {
super(looper);
}
public void handleMessage(final Message message) {
if (message != null) {
switch (message.what) {
case 2: {
final String data = (String)message.obj;
if (data != null) {
MyService.this.startMessageProcess(data);
return
}
break;
}
case 3: {
MyService.this.sendData((byte[])message.obj);
}
}
}
}
}
}
IMyService.java
public interface IMyService extends IInterface
{
void start_data(final String p0) throws RemoteException;
public abstract static class Stub extends Binder implements IMyService
{
public Stub() {
this.attachInterface((IInterface)this, "com.my.service.IMyService");
}
public static IMyService asInterface(final IBinder binder) {
if (binder == null) {
return null;
}
final IInterface queryLocalInterface = binder.queryLocalInterface("com.my.service.IMyService");
if (queryLocalInterface != null && queryLocalInterface instanceof IMyService) {
return (IMyService)queryLocalInterface;
}
return new Proxy(binder);
}
public IBinder asBinder() {
return (IBinder)this;
}
public boolean onTransact(final int code, final Parcel data, final Parcel reply, final int flags) throws RemoteException {
switch (code) {
case 1: {
data.enforceInterface("com.my.service.IMyService");
this.start_data(data.readString());
reply.writeNoException();
return true;
}
case 1000000000: {
reply.writeString("com.my.service.IMyService");
return true;
}
default: {
return super.onTransact(n, data, reply, flags);
}
}
}
private static class Proxy implements IMyService
{
private IBinder mRemote;
Proxy(final IBinder mRemote) {
this.mRemote = mRemote;
}
public IBinder asBinder() {
return this.mRemote;
}
public String getInterfaceDescriptor() {
return "com.my.service.IMyService";
}
@Override
public void start_data(final String data) throws RemoteException {
final Parcel data = Parcel.obtain();
final Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken("com.my.service.IMyService");
data.writeString(data);
this.mRemote.transact(1, data, reply, 0);
reply.readException();
}
finally {
reply.recycle();
data.recycle();
}
}
}
}
}
IHelperService.java
public interface IHelperService extends IInterface
{
// a bunch of method declarations here
public abstract static class Stub extends Binder implements IHelperService
{
public Stub() {
this.attachInterface((IInterface)this, "android.service.helper.IHelperService");
}
public static IHelperService asInterface(final IBinder binder) {
if (binder == null) {
if (queryLocalInterface != null && queryLocalInterface instanceof IHelperService) {
return (IHelperService)queryLocalInterface;
}
return new Proxy(binder);
}
}
public IBinder asBinder() {
return (IBinder)this;
}
public boolean onTransact(int code, final Parcel data, final Parcle reply, int flags) throws RemoteException {
switch (code) {
// does a bunch of bunch of stuff here based on the incoming code
}
}
}
private static class Proxy implements IHelperService
{
private IBinder mRemote;
Proxy(final IBinder mRemote) {
this.mRemote = mRemote;
}
@Override
// a bunch of method definitions here, everything that was declared above
}
}
我很难跟踪谁发送给谁的东西。例如,在IMyService的代理中,start_data调用transact(mRemote),但是谁是mRemote?另外,在MyService()构造函数以及startMessageProcess中,调用sendMessage,是谁发送给?
然后,MyService中有一些似乎不在本地调用的私有方法,例如startMessageProcess和getServerData。如果他们是私人的,还有谁可以称这些方法?