AIDL实践二:自定义数据类型
2017-01-20 14:38
239 查看
AIDL实践一:自定义类型传递
本文是慕课网视频的练习,视频网址:http://www.imooc.com/learn/606- 开发工具: Android Studio
一.编写服务端:
创建项目在java目录同级下创建aidl文件夹
创建IPersonAidl.aidl文件,文件内容如下:
// IAddAidl.aidl package com.lyj.aidldemo2; // Declare any non-default types here with import statements import com.lyj.aidldemo2.Person; interface IPersonAidl { //注意 in 表示输入,否则编译不过 List<Person> addPerson(in Person person); }
在java文件夹下创建类Person.java,有年龄和姓名两个字段,并实现Parcelable接口,代码如下:
//实现Parcelable public class Person implements Parcelable{ private int age; private String name; public Person(int age, String name) { this.age = age; this.name = name; } public Person(Parcel in) { //注意,此处顺序要和writeToParcel中的顺序一致 age = in.readInt(); name = in.readString(); } public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person createFromParcel(Parcel in) { return new Person(in); } @Override public Person[] newArray(int size) { return new Person[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(age); dest.writeString(name); } //重写toString方法 @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
在Aidl文件夹中创建Person.java同名的Person.aidl文件,文件内容如下:
package com.lyj.aidldemo2; parcelable Person;
在Java目录下创建远程服务IMyService,代码如下
public class IMyService extends Service { private List<Person> persons; @Nullable @Override public IBinder onBind(Intent intent) { //绑定服务时初始化persons对象 persons = new ArrayList<Person>(); return iBinder; } //实例化iBinder对象,实现IPersonAidl的方法 private IBinder iBinder = new IPersonAidl.Stub(){ @Override public List<Person> addPerson(Person person) throws RemoteException { persons.add(person); return persons; } }; }
在这个类中,实现了IAddAidl中的方法,在客户端绑定服务的时候,返回iBinder
在Manifest中注册:
<service android:name=".MyService" android:process=":remote" android:exported="true"/>
process 表示是一个远程服务
exported属性值为true,表示其它app可以引用这个服务。
到目前为止,服务端的工作已经完成了。
二.客户端编写
新建一个项目或新建一个module,名字为client将服务端的aidl文件夹拷贝到client下,和java目录同级,注意,拷贝后检查包名一定要和服务端的包名一样
在java下新建一个包,包名和服务端Person.java的包名一致,将person.java拷贝到此包下面,然后编译
编写客户端布局和代码
布局就是两个edittext输入年龄和姓名,一个button点击时触发远程服务的addPerson方法,一个TextView显示结果,此处就略去
代码如下:
public class MainActivity extends AppCompatActivity { private EditText et_name,et_age; private Button btn_print; private TextView tv_content; private IPersonAidl iPersonAidl; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iPersonAidl = IPersonAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { iPersonAidl = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initAction(); bindService(); } private void initAction() { btn_print.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String name = et_name.getText().toString().trim(); int age = Integer.parseInt(et_age.getText().toString().trim()); Person person = new Person(age,name); try { List<Person> persons = iPersonAidl.addPerson(person); tv_content.setText(persons.get(0).toString()); } catch (RemoteException e) { e.printStackTrace(); } } }); } private void bindService() { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.lyj.aidldemo2","com.lyj.aidldemo2.IMyService")); bindService(intent,conn, Context.BIND_AUTO_CREATE); } private void initView() { et_age = (EditText) findViewById(R.id.et_age); et_name = (EditText) findViewById(R.id.et_name); btn_print = (Button) findViewById(R.id.btn_print); tv_content = (TextView) findViewById(R.id.tv_content); } @Override protected void onDestroy() { super.onDestroy(); unbindService(conn); } }
首先,在onCreate()的时候绑定了服务
其次,在服务连接(onServiceConnect())时,获取IPersonAidl对象,
最后,在点击的时候,iAddAidl调用其addPerson(Person person)方法
三.运行
先运行服务端app,然后运行客户端app,在客户端的app中并未实现加到方法,却调用服务端的方法,实现了加的运算。四.总结:
可以看到,自定义类型的传递和基本类型的传递还是很相似的,但是要注意一下几点: 1. Person.java 和 Person.aidl文件名要相同,且Person.java中必须实现序列化 2. aidi接口中要输入的参数前面要加 in ,否则编译不过,会报如下错误:
C:\LYJ\new\AidlDemo2\app\src\main\aidl\com\lyj\aidldemo2\IPersonAidl.aidl:9 parameter 1: 'Person person' can be an out parameter, so you must declare it as in, out or inout. Error:Execution failed for task ':app:compileDebugAidl'. > java.lang.RuntimeException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Users\yu\AppData\Local\Android\sdk\build-tools\22.0.1\aidl.exe'' finished with non-zero exit value 1
3. 在客户端拷贝包的时候一定要把aidl文件和java文件都拷过去,拷完检查包名是否完整
相关文章推荐
- aec Gain 公式
- Codeforces Round #392(Div. 2) C Unfair Poll【思维+暴力】
- Codeforces 758C Unfair Poll
- Codeforces Round #392 (Div. 2)-C. Unfair Poll(xjb)
- saiku3.8二次开发项目搭建(非maven)
- poj_1691 Painting A Board(dfs+拓扑)
- Codeforces Round #392 (Div. 2) C. Unfair Poll
- 51 Nod 1305 Pairwise Sum and Divide (规律)
- 《机器学习实战》朴素贝叶斯(Naive Bayes)分类
- UNIX Domain Sockets
- Codeforces 758C Unfair Poll 暴力模拟
- UVA Fractions Again?! UVA - 10976
- Codeforces Round #392 (Div. 2) C - Unfair Poll codeforces
- The filename 未命名.ipa in the package contains an invalid character(s).
- The filename 未命名.ipa in the package contains an invalid character(s). The valid characters are: A-Z
- The filename 未命名.ipa in the package contains an invalid character(s). The valid characters are: A-Z, a-z, 0-9, dash, period, underscore, but the name cannot start with a dash, period, or underscore
- 2017美国数学建模ICM E题 可持续发展的城市需要(Sustainable Cities Needed!)
- 2017美国数学建模ICM D题 优化机场安全的乘客吞吐量检查点(Optimizing the Passenger Throughput at an Airport Security Checkpo)
- No grammar constraints (DTD or XML schema).....两种解决方法
- http://blog.csdn.net/wonderisland/article/details/22892759