1. 程式人生 > >Android例子—直接通過Binder的onTransact完成跨程序通訊

Android例子—直接通過Binder的onTransact完成跨程序通訊

Android可以通過Binder的onTrensact方法來完成通訊,下面就來簡單試下下,還是前面那個根據 序號查詢名字的例子:

服務端實現:

/**
 * Created by Jay on 2015/8/18 0018.
 */
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();
            }
        }
    }
}