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
- 进程间通讯[android]
- Android进程间通讯
- Android进程间通讯
- android aidl 进程间通讯
- android进程间通讯方式
- android IPC 进程间通讯
- Android IPC进程间通讯机制
- Android IPC进程间通讯机制
- Android IPC进程间通讯机制
- Android local socket 进程间通讯实验
- Android AIDl来实现进程间通讯
- android aidl进程间的通讯(笔记)
- Android进程间通讯——AIDL
- Android进程间通讯——ContentProvider
- Android进程间通讯之messenger
- Android进程间通讯之messenger
- Android进程间通讯之messenger
- Android 进程间通讯Binder异常总结
- 补c++第一次实验
- MNIST tensorflow官方卷积网络示例
- ocupload影响的按钮无效的原因
- 网络请求框架封装(NetWorkUtils)
- 推荐几个常用的GIT托管平台
- Android进程间通讯
- 数据结构之栈篇
- Android StatFs类
- 设计模式-单列模式
- 软件架构设计 首发于 软件架构设计 写文章 大型软件架构设计
- 软件设计师考试:设计模式
- 让vs2010支持html5
- JDBC操作数据库的步骤
- myEclipse 导入 jquery包报错