android 进程间通信(aidl)
2015-07-30 12:42
656 查看
注:由于时间关系目前先写个大概,后续再做完善
1.建立aidl
建立aidl文件夹,在文件夹中添加包tk.huayu.api,包中添加以下文件
IService.aidl
Test.aidl
Test2.aidl
2.实现aidl用到的对象
新建包tk.huayu.api,这个包必须和aidl中一模一样。在包中添加如下文件
Test.java
Test2.java
3.实现接口
新建包package tk.huayu.demo
MyService .java
4.声明service
AndroidManifest.xml
5.编写客户端
将service的aidl包和api包拷贝到客户端app中(包名不能改变)
MainActivity.java
AndroidManifest.xml
注:也可以在客户端实现类似IService接口,将接口实例通过参数注册到service,这样service也能远程调用客户端的函数,如果客户端有多个(一般也是有多个)可以使用RemoteCallbackList进行批量回调。
1.建立aidl
建立aidl文件夹,在文件夹中添加包tk.huayu.api,包中添加以下文件
IService.aidl
[code]package tk.huayu.api; import tk.huayu.api.Test; // 同一个包下面的也必须导包 interface IService{ // in表示这个参数是作为输入参数使用(in/out/inout),作为返回值时不用加 void fun1(in Test test); }
Test.aidl
[code]package tk.huayu.api; parcelable Test; // 声明Test对象
Test2.aidl
[code]package tk.huayu.api; parcelable Test2; // 声明Test2对象,这个是Test中包含的一个属性(对象)
2.实现aidl用到的对象
新建包tk.huayu.api,这个包必须和aidl中一模一样。在包中添加如下文件
Test.java
[code]package tk.huayu.api; import android.os.Parcel; import android.os.Parcelable; public class Test implements Parcelable { public int testInt=1; public String testString="Test"; public Test2 test2 = new Test2(); public Test(){ } int getTestInt(){ return testInt; } /** * 实现Parcelable接口必须实现的方法: * * @return 描述这一Parcel是起什么作用的,通过这一整形每个bit来描述其类型,一般会返回0 */ @Override public int describeContents() { return 0; } /** * 实现Parcelable接口必须实现的方法: * 将类所需要传输的属性写到Parcel里,在这个方法里都是使用writeXXX()写入到Parcel * @param dest 提供发送功能的Parcel * @param flags 用来指定这样的发送方向,与aidl的in、out、inout三种限定符匹配 */ @Override public void writeToParcel(Parcel dest, int flags) { //把该对象所包含的数据写到Parcel dest.writeInt(testInt); dest.writeString(testString); //dest.writeParcelable(test2,flags); dest.writeValue(test2); } /** * 这个构造方法用于从序列化数据中取出数据。读取的顺序要和writeToParcel()写入的顺序一致 * @param source 数据源 */ private Test(Parcel source){ testInt = source.readInt(); testString = source.readString(); test2 = (Test2)source.readValue(Test2.class.getClassLoader()); } /** * 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口 */ public static final Parcelable.Creator<Test> CREATOR = new Parcelable.Creator<Test>(){ /** * 从Parcel中读取数据,返回Test对象。读取的顺序要和writeToParcel()写入的顺序一致 * @param source 数据源 * @return 接收到的对象(通过数据源创建的一个对象) */ @Override public Test createFromParcel(Parcel source){ return new Test(source); } /** * 用于创建多个这种实现了Parcelable接口的类。创建多个空对象,不能以某个Parcel对象为基础创建,使用默认的类创始化方法。 * @param size 数组大小 * @return 数组 */ @Override public Test[] newArray(int size){ return new Test[size]; } }; }
Test2.java
[code]package tk.huayu.api; import android.os.Parcel; import android.os.Parcelable; public class Test2 implements Parcelable { public int testInt=2; public String testString="Test2"; public Test2(){ } int getTestInt(){ return testInt; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(testInt); dest.writeString(testString); } private Test2(Parcel source){ testInt = source.readInt(); testString = source.readString(); } public static final Parcelable.Creator<Test2> CREATOR = new Parcelable.Creator<Test2>(){ @Override public Test2 createFromParcel(Parcel source){ return new Test2(source); } @Override public Test2[] newArray(int size){ return new Test2[size]; } }; }
3.实现接口
新建包package tk.huayu.demo
MyService .java
[code]package tk.huayu.demo; import android.app.Service; import android.os.IBinder; import android.content.Context; import tk.huayu.api.IService; public class MyService extends Service{ /** * 被远程调用,运行在appliction1进程中的Binder_x线程(查看进程号 android.os.Process.myPid()) */ public IService.Stub stub = new IServiceInterface(); public class IServiceInterface extends IService.Stub // 注意实现的一定要是Stub,否者远端调用得到的将是null() { // 实现AIDL文件中接口的定义的各个方法。 public void fun1(Test test){ // 不再注明in,添加public ... // 代码略 Log.d("IService","fun1:"+test); } } @Override protected void onCreate(Bundle savedInstanceState) { ... // 代码略 } @Override public IBinder onBind(Intent intent) { Log.d("MyService ", "onBind "+android.os.Process.myPid()); return stub; } @Override public boolean onUnbind(Intent intent) { Log.d("MyService ", "onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); } }
4.声明service
AndroidManifest.xml
[code]<?xml version="1.0" encoding="utf-8"?> <manifest ... > <!-- 添加service外部访问许可(不添加也可以,只是提示警告)。当然,如果service添加了许可,那么客户端也要添加许可 <uses-permission android:name="tk.huayu.edog"/>, 否则客户端访问时将抛出异常 --> <permission android:protectionLevel="normal" android:name="tk.huayu.demo"/> <application ... > <!-- 声明service,要添加 android:exported="true"否则service是不允许外部的应用进行远程调用 android:process=":remote" // 添加这边表示service在独立的进程运行 --> <service android:name="tk.huayu.demo.MyService" android:exported="true" android:permission="tk.huayu.demo" /> ... </application> </manifest>
5.编写客户端
将service的aidl包和api包拷贝到客户端app中(包名不能改变)
MainActivity.java
[code]public class MainActivity extends Activity { private ServiceConnection serviceConnection = new ServiceConnection(){ @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("Client","onServiceConnected "+name+"IBinder "+service); IService service = IService.Stub.asInterface(service); if(service!=null) { try { Log.d("Client", "call fun1"); service.fun1(new Test()); } catch (RemoteException e) { e.printStackTrace(); Log.d("Client", "service is bad"); } } } @Override public void onServiceDisconnected(ComponentName name) { Log.d("Client","onServiceConnected "+name); } }; @Override protected void onCreate(Bundle savedInstanceState) { ... Intent i = new Intent(); i.setClassName("tk.huayu.demo","tk.huayu.demo.MyService"); this.context.bindService(i, serviceConnection, Context.BIND_AUTO_CREATE); Log.d("Client", "service bind "+android.os.Process.myPid()); } @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection); } }
AndroidManifest.xml
[code]<?xml version="1.0" encoding="utf-8"?> <manifest ... > <!-- 添加许可 --> <uses-permission android:name="tk.huayu.demo"/> <application ... > ... </application> </manifest>
注:也可以在客户端实现类似IService接口,将接口实例通过参数注册到service,这样service也能远程调用客户端的函数,如果客户端有多个(一般也是有多个)可以使用RemoteCallbackList进行批量回调。
相关文章推荐
- Android实践 - 7-29
- Android实践 7-28
- Android实践 7-27
- android 实践 7/25
- Android 实践 7-24
- Android文字点击时变色
- android实践-2015-07-21
- 几款有用的AndroidStudio插件
- 几款有用的AndroidStudio插件
- 微软提供的android模拟器
- android 安装与ADT安装
- Android端页面加速记录
- 我的Android进阶之旅------>Android关于Activity管理的一个简单封装
- android开发遇到的问题
- Android反射drawable
- Android图片处理
- 使用Java代码来比较Android客户端版本号
- android的MainActivity中setOnClickListener(this)中的this指代
- 【Android测试】【第六节】Monkey——认识和使用
- android sdk下载地址