Aidl在项目中的使用
2016-05-04 10:47
501 查看
Aidl
Aidl是一个进程间通信的一个语言,通过他我们可以在不同应用之间通讯,不管有多少应用都可以,但是前提是必须要使用同一份定义好的aidl文件,这个文件包含的有aidl类型的文件,已经继承了Parcelable的要在aidl中传输的类。
现在网上很多例子中对于Aidl的讲解其实是很详细的,但是可能在开发中还是会有不同的问题,我算是总结吧。
关于aidl的流程:
(1) 服务端创建aidl文件,aidl文件创建的时候可以是在任意包下创建,但是一般很多人都会专门为他创建一个包,
(2) 书写aidl文件,他的写法是这样的:
第一行是这个文件当前所在的包名, 然后下边可以导入他要用到的类的,然后就是这个接口类的定义“
(4) 然后在清单文件中把这个service进行注册,然后指定Action。在客户端要通过这个Action来进行绑定,服务端就写完了。
(5) 上边的服务端写完以后,然后就是客户端了,客户端相对更简单,只要把服务端的aidl包直接拷贝一份放到客户端就好,但是记得要删除service文件,然后你就会看到客户端gen文件下边也生成了aidl文件
(6) 客户端进行绑定就可以进行通信了
上边基本上市一个简单的aidl的写法,那么如果我们要在Aidl中传递跟使用实体类对象呢,
那么就要创建相应的aidl文件,还有跟它同名的实现了Parcelable借口的类,应为传递的时候必须是序列化才能进行传递,还有一点要注意的就是,跟它同名的实现了Parcelable接口的类不能是抽象类。
下边看一个实体类的实现步骤:
(1)首先创建Aidl文件,然后编写aidl文件 ,里边的代码是这样的:
(2)同名实体类的书写
这样的话一个实体类就ok了。
但是有的时候我们可能还会用到别的东西,比如可能要写一个监听器,还有回调的callBack的话他该如何写呢?
写法其实类似:
这样就ok了。
总结:
aidl可以实现Android手机上边应用间的相互访问,可以以实现不类似其中一个app有改动的时候通知其他所有的app的功能(类似广播功能),还可以通过远程aidl实现html上边跟客户端的交互,其中就需要用到类似监听器。
下边把我写的Demo附上:Demo,Demo是可以实现类似广播的功能,但是前提是你的app要都打开才行,如果能熟练这个Demo的话基本上Aidl没有任何问题了
Aidl是一个进程间通信的一个语言,通过他我们可以在不同应用之间通讯,不管有多少应用都可以,但是前提是必须要使用同一份定义好的aidl文件,这个文件包含的有aidl类型的文件,已经继承了Parcelable的要在aidl中传输的类。
现在网上很多例子中对于Aidl的讲解其实是很详细的,但是可能在开发中还是会有不同的问题,我算是总结吧。
关于aidl的流程:
(1) 服务端创建aidl文件,aidl文件创建的时候可以是在任意包下创建,但是一般很多人都会专门为他创建一个包,
(2) 书写aidl文件,他的写法是这样的:
第一行是这个文件当前所在的包名, 然后下边可以导入他要用到的类的,然后就是这个接口类的定义“
package com.braincol.aidl.service; import com.braincol.aidl.service.Beauty; import com.braincol.aidl.service.OnChangeListener; interface RemoteBeauty { void setListener(in OnChangeListener listener); void notify(in String s,in OnChangeListener listener); }(3) 然后就会在gen文件夹下生成相应的aidl文件(ecplise中),然后自己写一个service,里边通过IBinder来返回aidl对象
package com.braincol.aidl.service; import java.util.ArrayList; import java.util.List; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; /** *提供服务的service */ public class RemoteService extends Service { private final static String TAG = "RemoteService"; private List<OnChangeListener> list = new ArrayList<OnChangeListener>(); @Override public IBinder onBind(Intent intent) { Log.i(TAG, "执行了OnBind"); return new MyBinder(); } private class MyBinder extends RemoteBeauty.Stub{ @Override public void notify(String s, OnChangeListener listener) throws RemoteException { Log.e("TAG", "NOTIFY"); Log.e("TAG", list.size()+""); if (list.size() >0) { for (int i = 0; i < list.size(); i++) { list.get(i).getINotifyCallBack().onStringChange(s);; } } } @Override public void setListener(OnChangeListener listener) throws RemoteException { list.add(listener); }} }
(4) 然后在清单文件中把这个service进行注册,然后指定Action。在客户端要通过这个Action来进行绑定,服务端就写完了。
(5) 上边的服务端写完以后,然后就是客户端了,客户端相对更简单,只要把服务端的aidl包直接拷贝一份放到客户端就好,但是记得要删除service文件,然后你就会看到客户端gen文件下边也生成了aidl文件
(6) 客户端进行绑定就可以进行通信了
package com.example.test2; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import com.braincol.aidl.service.INotifyCallback; import com.braincol.aidl.service.OnChangeListener; import com.braincol.aidl.service.RemoteBeauty; public class MainActivity extends Activity { private Button button; private RemoteBeauty remoteBeauty; private INotifyCallback iNotifyCallback = new INotifyCallback() { @Override public IBinder asBinder() { return new INotifyCallback.Stub() { @Override public void onStringChange(String str) throws RemoteException { button.setText(str); } }; } @Override public void onStringChange(String str) throws RemoteException { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.btn_); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction("com.braincol.aidl.remote"); bindService(intent, new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "连接", 1000).show(); remoteBeauty = RemoteBeauty.Stub.asInterface(service); try { remoteBeauty.setListener(new OnChangeListener(iNotifyCallback)); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, Context.BIND_AUTO_CREATE); } }); Button button_1 = (Button)findViewById(R.id.btn_1); button_1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { remoteBeauty.notify("我要改變你", null); } catch (RemoteException e) { e.printStackTrace(); } } }); } }
上边基本上市一个简单的aidl的写法,那么如果我们要在Aidl中传递跟使用实体类对象呢,
那么就要创建相应的aidl文件,还有跟它同名的实现了Parcelable借口的类,应为传递的时候必须是序列化才能进行传递,还有一点要注意的就是,跟它同名的实现了Parcelable接口的类不能是抽象类。
下边看一个实体类的实现步骤:
(1)首先创建Aidl文件,然后编写aidl文件 ,里边的代码是这样的:
<span style="white-space:pre"> </span>package com.braincol.aidl.service; <span style="white-space:pre"> </span>parcelable Person;
(2)同名实体类的书写
package com.braincol.aidl.service; import android.os.Parcel; import android.os.Parcelable; /** *Parcelable是android提供的一个比serializable效率更高的序列号接口这里必须要继承Parcelable! * 在实体类我们要做两件重要的事情: * 第一:实现Parcelable接口 * 第二:定义一个Parcelable.Creator类型的CREATOR对象 * 第三:要提供一个Person.aidl文件,其中内容为parcelable Beauty,定义了之后,在其他aidl文件中引用Beauty时便不会提示出错了。 */ public class Person implements Parcelable { String name ; int age ; String sex ; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public int describeContents() { return 0; } /** * 将对象序列号 * dest 就是对象即将写入的目的对象 * flags 有关对象序列号的方式的标识 * 这里要注意,写入的顺序要和在createFromParcel方法中读出的顺序完全相同。例如这里先写入的为name, * 那么在createFromParcel就要先读name */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); dest.writeString(sex); } /** * 在想要进行序列号传递的实体类内部一定要声明该常量。常量名只能是CREATOR,类型也必须是 * Parcelable.Creator<T> */ public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() { /** * 创建一个要序列号的实体类的数组,数组中存储的都设置为null */ @Override public Person[] newArray(int size) { return new Person[size]; } /*** * 根据序列号的Parcel对象,反序列号为原本的实体对象 * 读出顺序要和writeToParcel的写入顺序相同 */ @Override public Person createFromParcel(Parcel source) { String name = source.readString(); int age = source.readInt(); String sex = source.readString(); Person person = new Person(); person.setName(name); person.setAge(age); person.setSex(sex); return person; } }; }
这样的话一个实体类就ok了。
但是有的时候我们可能还会用到别的东西,比如可能要写一个监听器,还有回调的callBack的话他该如何写呢?
写法其实类似:
package com.braincol.aidl.service; parcelable OnChangeListener;
package com.braincol.aidl.service; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; // 不嫩使用抽象类 public class OnChangeListener implements Parcelable{ private INotifyCallback callback; public OnChangeListener (INotifyCallback callback){ this.callback = callback; } public void setINotifyCallback(INotifyCallback iNotifyCallback){ this.callback = iNotifyCallback; } public INotifyCallback getINotifyCallBack(){ return callback; } // 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口 public static final Parcelable.Creator<OnChangeListener> CREATOR = new Creator<OnChangeListener>() { @Override public OnChangeListener[] newArray(int size) { // TODO Auto-generated method stub return new OnChangeListener[size]; } @Override public OnChangeListener createFromParcel(Parcel source) { OnChangeListener listener = new OnChangeListener(INotifyCallback.Stub.asInterface(source.readStrongBinder())); return listener; } }; @Override public int describeContents() { // TODO Auto-generated method stub return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeStrongBinder(callback.asBinder()); } }
这样就ok了。
总结:
aidl可以实现Android手机上边应用间的相互访问,可以以实现不类似其中一个app有改动的时候通知其他所有的app的功能(类似广播功能),还可以通过远程aidl实现html上边跟客户端的交互,其中就需要用到类似监听器。
下边把我写的Demo附上:Demo,Demo是可以实现类似广播的功能,但是前提是你的app要都打开才行,如果能熟练这个Demo的话基本上Aidl没有任何问题了
相关文章推荐
- 深入解读Android的内部进程通信接口AIDL
- Android应用程序四大组件之使用AIDL如何实现跨进程调用Service
- 使用Android studio创建的AIDL编译时找不到自定义类的解决办法
- Android AIDL和远程Service调用示例代码
- Android中如何利用AIDL机制调用远程服务
- 基于Android AIDL进程间通信接口使用介绍
- Android 使用【AIDL】调用外部服务的解决方法
- Android程序设计之AIDL实例详解
- 实例讲解Android中的AIDL内部进程通信接口使用
- 浅谈Android Aidl 通讯机制
- Android AIDL 原理解析
- Android 使用 AIDL 实现进程间通信,使用基本类型作为输入和输出参数
- AIDL入门
- 绑定服务 aidl 的应用
- android AIDL通信
- [Android] AIDL浅析
- aidl远程服务调用
- android service 和aidl
- android的AIDL----讲述进程间通信
- android工程混淆时要注意的