直接通过Binder的onTransact完成跨进程通信
1.具体代码:
服务端实现:
public class IPCService extends Service { private static final String DESCRIPTOR = "IPCService"; private final String[] names = { "B神", "艹神", "基神", "J神", "翔神" }; private MyBinder mBinder = new MyBinder(); private class MyBinder extends Binder { @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case 0x001: { data.enforceInterface(DESCRIPTOR); int num = data.readInt(); reply.writeNoException(); reply.writeString(names[num]); return true; } } return super.onTransact(code, data, reply, flags); } } @Override public IBinder onBind(Intent intent) { return mBinder; } }
可以看到onTransact有四个参数
code , data ,replay , flags
- code 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法;
- data客户端传递过来的参数;
- replay服务器返回回去的值;
- flags标明是否有返回值,0为有(双向),1为没有(单向)。
客户端实现:
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private EditText edit_num; private Button btn_query; private TextView txt_result; private IBinder mIBinder; private ServiceConnection PersonConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mIBinder = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { mIBinder = service; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindViews(); // 绑定远程Service Intent service = new Intent("android.intent.action.IPCService"); service.setPackage("com.jay.ipcserver"); bindService(service, PersonConnection, BIND_AUTO_CREATE); btn_query.setOnClickListener(this); } private void bindViews() { edit_num = (EditText) findViewById(R.id.edit_num); btn_query = (Button) findViewById(R.id.btn_query); txt_result = (TextView) findViewById(R.id.txt_result); } @Override public void onClick(View v) { int num = Integer.parseInt(edit_num.getText().toString()); if (mIBinder == null) { Toast.makeText(this, "未连接服务端或服务端被异常杀死", Toast.LENGTH_SHORT).show(); } else { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); String _result = null; try { _data.writeInterfaceToken("IPCService"); _data.writeInt(num); mIBinder.transact(0x001, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); txt_result.setText(_result); edit_num.setText(""); } catch (RemoteException e) { e.printStackTrace(); } finally { _reply.recycle(); _data.recycle(); } } } }
2.transact和onTransact的区别
谈transact 和onTransact需要先聊聊iBinder
IBinder是什么呢?首先要明白,Android的远程调用(就是跨进程调用)就是通过IBinder实现的,下面是对android开发文档的翻译。
IBinder是远程对象的基本接口,是为高性能而设计的轻量级远程调用机制的核心部分。但它不仅用于远程调用,也用于进程内调用。这个接口定义了与远程对象交互的协议。不要直接实现这个接口,而应该从Binder派生。