刚开始学习安卓的时候学过怎么跨应用启动activity和servicer,但只是会启动而已,对于他们之间的通信并没有做更深入的了解。偶尔接触到一个名词叫AIDL,在网上查阅资料的时候发现他的全称为android interface definition language,即安卓接口定义语言,官方文档上的note: Using AIDL is necessary only if you allow clients fromdifferent applications to access your service for IPC and want to handlemultithreading in your service.
其值IPC为interprocesscommunication ,即跨进程通信,AIDL在绑定Service时要用到,那为什么要绑定Service呢?
我们知道有启动Service和绑定Service而且启动Service貌似更简单一些,但当我们要和Service进行通信时,就要用到绑定Service,而简单的启动Service却不能达到通信的目的。
下面通过一个实例来介绍AIDL的应用:
具体的假面布局不再给出,
创建一个名为app01的应用,他负责启动另一个应用app02内的activity和service并进行通信。
app01:package syd.myaidl; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; import syd.myapplication.IMyAidlInterface; public class MainActivity extends AppCompatActivity { Intent intent; EditText editText; TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText= (EditText) findViewById(R.id.edtext); textView= (TextView) findViewById(R.id.tv); intent = new Intent(); //跨应用启动或绑定service和activity不像本应用内那样可以获取到所要启动或绑定的服务或activity的类 //并且安卓5.0之后必须要通过显示intent来启动服务 //当然方法还是有的,就是通过intent的setComponent方法来设置 //第一个参数为所要启动的服务或activity所在的包名 //第二个参数为包名+类名 intent.setComponent(new ComponentName("syd.myapplication", "syd.myapplication.MyService")); findViewById(R.id.btnstart).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //跨应用启动service startService(intent); } }); findViewById(R.id.btnstop).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //结束service stopService(intent); } }); findViewById(R.id.btnbind).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //绑定service //第一个参数为intent,第二个为ServiceConnection,负责接收绑定成功和解除绑定的消息,这也是通信的的关键所在 //第三个为flags,绑定时的选项,可以自行阅读官方文档 // http://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int) bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } }); findViewById(R.id.btnunbind).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //解除绑定 unbindService(serviceConnection); iMyAidlInterface=null; } }); findViewById(R.id.sync).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (iMyAidlInterface != null) { try { iMyAidlInterface.setData(editText.getText().toString()); textView.setText(iMyAidlInterface.getData().toString()); } catch (RemoteException e) { e.printStackTrace(); } } } }); findViewById(R.id.btnstartActivity).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //跨应用启动activity, Intent i=new Intent(); i.setComponent(new ComponentName("syd.myapplication","syd.myapplication.MainActivity")); startActivity(i); } }); } ServiceConnection serviceConnection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("service binded!"); //获取IBinder //地址不同不能使用强制cast iMyAidlInterface=IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { System.out.println("service disbinded!"); iMyAidlInterface=null; } }; private IMyAidlInterface iMyAidlInterface=null; }
然后建立app02:并建立Service和mainactivity:
在App01中家里一个AIDL文件:
// IMyAidlInterface.aidl package syd.myapplication; // Declare any non-default types here with import statements interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); //附加接口方法,根据自己需求添加,在这里添加了setData和getData void setData(String data); String getData(); }Service类:
package syd.myapplication; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; /** * Created by Admin on 2015/10/21. */ public class MyService extends Service { @Override public IBinder onBind(Intent intent) { //这是关键,在这里返回建立的AIDL对象, // 在这里要实现AIDLIMyAidlInterface的接口方法 return new IMyAidlInterface.Stub() { @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public void setData(String data) throws RemoteException { dataed=data; } @Override public String getData() throws RemoteException { return backdata; } }; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); Thread thread=new Thread(new Runnable() { @Override public void run() { while (true) { System.out.println(dataed); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); thread.start(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); System.out.println("Service Started"); } @Override public void onDestroy() { super.onDestroy(); System.out.println("Service Destroyrd"); } String dataed="默认数据"; String backdata ="回传数据"; }另一个关键步骤:
在App1中新建一个文件夹aidl,在aidl下新建一个包,注意包名必须和app02中AIDL文件所在包名相同,然后将App02中的AIDL文件拷贝到App01中新建的包下即可
在App02的配置文件中配置:
<service android:name=".MyService" android:enabled="true" android:exported="true"> </service>
<activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 若不是<action android:name="android.intent.action.MAIN" />必须添加
![]()