Android进程间通讯

来源:互联网 发布:淘宝优惠券名称怎么写 编辑:程序博客网 时间:2024/05/16 23:56

AIDL

  • 服务端
    ① 在com.cjf.aidldemo包下新建 IMyAidlInterface.aidl文件
package com.cjf.aidldemo;interface IMyAidlInterface {/** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */  int add(int x , int y);  int min(int x , int y); }

  ②在com.cjf.aidldemo包下新建 IMyAidlInterface.aidl文件:

public class CalcService extends Service {private static final String TAG="server";@Nullable@Overridepublic IBinder onBind(Intent intent) {    Log.e(TAG,"onBind");    return mBinder;}@Overridepublic void onDestroy() {    Log.e(TAG,"onDestroy");    super.onDestroy();}@Overridepublic boolean onUnbind(Intent intent) {    Log.e(TAG,"onUnbind");    return super.onUnbind(intent);}@Overridepublic void onRebind(Intent intent) {    Log.e(TAG,"onRebind");    super.onRebind(intent);}@Overridepublic void onCreate() {    Log.e(TAG,"onCreate");    super.onCreate();}private final IMyAidlInterface.Stub mBinder=new IMyAidlInterface.Stub() {    @Override    public int add(int x, int y) throws RemoteException {        return x+y;    }    @Override    public int min(int x, int y) throws RemoteException {        return x-y;    }};

③在AndroidManifest.xml注册service

<application    android:allowBackup="true"    android:label="@string/app_name"    android:theme="@style/AppTheme">    <!--注意activity的配置,这样才能在4.0之后不在桌面显示图标-->    <activity        android:name=".MainActivity"        android:excludeFromRecents="true"        >        <intent-filter>            <action android:name="android.intent.action.MAIN"/>            <category android:name="android.intent.category.LAUNCHER"/>            <data                android:host="MainActivity"                android:scheme="com.cjf.aidldemo"/>        </intent-filter>    </activity>    <service android:name="com.cjf.aidldemo.CalcService">        <intent-filter>            <action android:name="com.cjf.aidldemo.calc"/>            <category android:name="android.intent.category.DEFAULT"/>        </intent-filter>    </service></application>

  ④实现Client端:新建工程
  新建IMyAidlInterface.aidl
  注意:包名要保持一致,内容相同。(直接复制过来就行)

private AppCompatButton bindservice_btn;private AppCompatButton unbindservice_btn;private AppCompatButton invokeadd_btn;private AppCompatButton invokemin_btn;private IMyAidlInterface mIMyAidlInterface;private ServiceConnection mServiceConnection = new ServiceConnection() {    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        Log.e("client", "onServiceConnected");        mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);    }    @Override    public void onServiceDisconnected(ComponentName name) {        Log.e("client", "onServiceDisconnected");        mIMyAidlInterface = null;    }};/** * 高版本中实现隐式调用 * @param context * @param implicitIntent * @return */public static Intent getExplicitIntent(Context context, Intent implicitIntent) {    // Retrieve all services that can match the given intent    PackageManager pm = context.getPackageManager();    List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);    // Make sure only one match was found    if (resolveInfo == null || resolveInfo.size() != 1) {        return null;    }    // Get component info and create ComponentName    ResolveInfo serviceInfo = resolveInfo.get(0);    String packageName = serviceInfo.serviceInfo.packageName;    String className = serviceInfo.serviceInfo.name;    ComponentName component = new ComponentName(packageName, className);    // Create a new intent. Use the old one for extras and such reuse    Intent explicitIntent = new Intent(implicitIntent);    // Set the component to be explicit    explicitIntent.setComponent(component);    return explicitIntent;}@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    bindservice_btn = (AppCompatButton) findViewById(R.id.bindservice_btn);    unbindservice_btn = (AppCompatButton) findViewById(R.id.unbindservice_btn);    invokeadd_btn = (AppCompatButton) findViewById(R.id.invokeadd_btn);    invokemin_btn = (AppCompatButton) findViewById(R.id.invokemin_btn);    bindservice_btn.setOnClickListener(this);    unbindservice_btn.setOnClickListener(this);    invokeadd_btn.setOnClickListener(this);    invokemin_btn.setOnClickListener(this);}@Overridepublic void onClick(View v) {    switch (v.getId()) {        case R.id.bindservice_btn:            bindService();            break;        case R.id.unbindservice_btn:            unbindService();            break;        case R.id.invokeadd_btn:            try {                addInvoked();            } catch (RemoteException e) {                e.printStackTrace();            }            break;        case R.id.invokemin_btn:            try {                minInvoked();            } catch (RemoteException e) {                e.printStackTrace();            }            break;    }}public void bindService() {    Intent mIntent = new Intent();    mIntent.setAction("com.cjf.aidldemo.calc");    Intent eintent = new Intent(getExplicitIntent(this,mIntent));    //注意这样才能实现隐式调用,不然会出异常    boolean plus = bindService(eintent, mServiceConnection, Context.BIND_AUTO_CREATE);    Log.e("plus", "" + plus);}public void unbindService() {    unbindService(mServiceConnection);}public void addInvoked() throws RemoteException {    if (mIMyAidlInterface != null) {        int result = mIMyAidlInterface.add(12, 13);        Toast.makeText(this, "" + result, Toast.LENGTH_SHORT).show();    } else {        Toast.makeText(this, "服务端异常,请重新绑定", Toast.LENGTH_SHORT).show();    }}public void minInvoked() throws RemoteException {    if (mIMyAidlInterface != null) {        int result = mIMyAidlInterface.min(50, 20);        Toast.makeText(this, "" + result, Toast.LENGTH_SHORT).show();    } else {        Toast.makeText(this, "服务端异常,请重新绑定", Toast.LENGTH_SHORT).show();    }}

不依赖ADIL实现进程间通讯

  • 服务端:
public class CalcService2 extends Service {private static final String DESCRIPTOR = "CalcService2";private static final String TAG = "CalcService2";@Nullable@Overridepublic IBinder onBind(Intent intent) {    Log.e(TAG,"onBind");    return mMyBinder;}@Overridepublic void onCreate() {    Log.e(TAG,"onCreate");    super.onCreate();}@Overridepublic void onDestroy() {    Log.e(TAG,"onDestroy");    super.onDestroy();}@Overridepublic boolean onUnbind(Intent intent) {    Log.e(TAG,"onUnbind");    return super.onUnbind(intent);}@Overridepublic void onRebind(Intent intent) {    Log.e(TAG,"onRebind");    super.onRebind(intent);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    Log.e(TAG,"onStartCommand");    return super.onStartCommand(intent, flags, startId);}private MyBinder mMyBinder=new MyBinder();private class MyBinder extends Binder{    @Override    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {        switch (code){            case 10010: { //乘法                //这里代码可以查看AIDL.stub                data.enforceInterface(DESCRIPTOR);                int _arg0;                _arg0 = data.readInt();                int _arg1;                _arg1 = data.readInt();                int _result = _arg0 * _arg1;                reply.writeNoException();                reply.writeInt(_result);                return true;            }            case 10086: { //除法                data.enforceInterface(DESCRIPTOR);                int _arg0;                _arg0 = data.readInt();                int _arg1;                _arg1 = data.readInt();                int _result = _arg0 / _arg1;                reply.writeNoException();                reply.writeInt(_result);                return true;            }        }        return super.onTransact(code, data, reply, flags);    }} <service android:name=".CalcService2">        <intent-filter>            <action android:name="com.cjf.aidldemo.calc2"/>            <category android:name="android.intent.category.DEFAULT"/>        </intent-filter>    </service>
  • 客户端:
public class NoAidlActivity extends AppCompatActivity implements View.OnClickListener {private IBinder mBinder;private AppCompatButton bindservice_btn;private AppCompatButton unbindservice_btn;private AppCompatButton invokeadd_btn;private AppCompatButton invokemin_btn;private ServiceConnection mServiceConnection = new ServiceConnection() {    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        Log.e("client", "onServiceConnected");        mBinder=service;    }    @Override    public void onServiceDisconnected(ComponentName name) {        Log.e("client", "onServiceDisconnected");    }};/** * 高版本中实现隐式调用 * * @param context * @param implicitIntent * @return */public static Intent getExplicitIntent(Context context, Intent implicitIntent) {    // Retrieve all services that can match the given intent    PackageManager pm = context.getPackageManager();    List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);    // Make sure only one match was found    if (resolveInfo == null || resolveInfo.size() != 1) {        return null;    }    // Get component info and create ComponentName    ResolveInfo serviceInfo = resolveInfo.get(0);    String packageName = serviceInfo.serviceInfo.packageName;    String className = serviceInfo.serviceInfo.name;    ComponentName component = new ComponentName(packageName, className);    // Create a new intent. Use the old one for extras and such reuse    Intent explicitIntent = new Intent(implicitIntent);    // Set the component to be explicit    explicitIntent.setComponent(component);    return explicitIntent;}@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_noaidl);    bindservice_btn = (AppCompatButton) findViewById(R.id.bindservice_btn);    unbindservice_btn = (AppCompatButton) findViewById(R.id.unbindservice_btn);    invokeadd_btn = (AppCompatButton) findViewById(R.id.invokeadd_btn);    invokemin_btn = (AppCompatButton) findViewById(R.id.invokemin_btn);    bindservice_btn.setOnClickListener(this);    unbindservice_btn.setOnClickListener(this);    invokeadd_btn.setOnClickListener(this);    invokemin_btn.setOnClickListener(this);}@Overridepublic void onClick(View v) {    switch (v.getId()) {        case R.id.bindservice_btn:            bindService();            break;        case R.id.unbindservice_btn:            unbindService();            break;        case R.id.invokeadd_btn:            try {                mulInvoked();            } catch (RemoteException e) {                e.printStackTrace();            }            break;        case R.id.invokemin_btn:            try {                divInvoked();            } catch (RemoteException e) {                e.printStackTrace();            }            break;    }}public void bindService() {    Intent mIntent = new Intent();    mIntent.setAction("com.cjf.aidldemo.calc2");    Intent eintent = new Intent(getExplicitIntent(this, mIntent));    //注意这样才能实现隐式调用,不然会出异常    boolean plus = bindService(eintent, mServiceConnection, Context.BIND_AUTO_CREATE);    Log.e("plus", "" + plus);}public void unbindService() {    unbindService(mServiceConnection);}public void mulInvoked() throws RemoteException {    if (mBinder != null) {        //查看AIDL实现方法,其实原理还是一样的        android.os.Parcel _data = android.os.Parcel.obtain();        android.os.Parcel _reply = android.os.Parcel.obtain();        int _result;        try        {            _data.writeInterfaceToken("CalcService2");//CalcService2就是服务端的DESCRIPTOR            _data.writeInt(5);            _data.writeInt(6);            mBinder.transact(10010, _data, _reply, 0);            _reply.readException();            _result = _reply.readInt();            Toast.makeText(this, _result + "", Toast.LENGTH_SHORT).show();        } catch (RemoteException e)        {            e.printStackTrace();        } finally        {            _reply.recycle();            _data.recycle();        }    } else {        Toast.makeText(this, "服务端异常,请重新绑定", Toast.LENGTH_SHORT).show();    }}public void divInvoked() throws RemoteException {    if (mBinder != null) {        android.os.Parcel _data = android.os.Parcel.obtain();        android.os.Parcel _reply = android.os.Parcel.obtain();        int _result;        try {            _data.writeInterfaceToken("CalcService2");            _data.writeInt(18);            _data.writeInt(3);            mBinder.transact(10086, _data, _reply, 0);            _reply.readException();            _result = _reply.readInt();            Toast.makeText(this, _result + "", Toast.LENGTH_SHORT).show();        }        finally {            _reply.recycle();            _data.recycle();        }    } else {        Toast.makeText(this, "服务端异常,请重新绑定", Toast.LENGTH_SHORT).show();    }}}

  这样就实现了不依赖与AIDL的进程间通讯,底层的实现是一样的ADIL做了很多工作, 简化了整个实现。

Demo下载

0 0