AIDL最佳实践
来源:互联网 发布:手机网络不卡玩游戏卡 编辑:程序博客网 时间:2024/06/07 22:10
参考:Android 接口定义语言 (AIDL)
之前在Eclipse中进行过AIDL的实践,昨天又尝试着在AndroidStudio中实践,看了一些博客,感觉很多步骤还是没说清楚,耽误了一些时间。下面就整理一下关于AIDL实践的详细过程。
1.创建工程
工程名字叫AIDL_practice,有两个可以运行的module,client和server。顾名思义,client就是AIDL实践中的客户端,server是服务端。
2.初始化server
在server的src/main目录下创建AIDL文件,IMyAidl.aidl:
并且在其中添加一个add方法:
然后build一下server这个module,发现IDE为我们生成了一个名叫IMyAidl的Java文件:
这个时候我们就可以新建Service了:
最后别忘记在AndroidManifest.xml文件中声明Service的权限:
<service android:name=".RemoteService" android:enabled="true" android:exported="true"/>
3.初始化client
然后我们把之前自己写的AIDL文件,IMyAidl.aidl,copy到client的同名目录下
再build一下client这个module,IDE同样为我们生成了一个名叫IMyAidl的Java文件,然后我们就开始写客户端逻辑了:
public class ClientActivity extends AppCompatActivity { private IMyAidl iMyAidl; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iMyAidl = IMyAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { iMyAidl = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_client); initView(); bindService(); } private void initView() { final EditText num1Edt = (EditText) findViewById(R.id.num1); final EditText num2Edt = (EditText) findViewById(R.id.num2); Button addBtn = (Button) findViewById(R.id.add); final TextView resultTv = (TextView) findViewById(R.id.result); addBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String num1 = num1Edt.getText().toString().trim(); String num2 = num2Edt.getText().toString().trim(); if (TextUtils.isEmpty(num1)) { Toast.makeText(ClientActivity.this, "请输入第一个数字", Toast.LENGTH_LONG).show(); } else if (TextUtils.isEmpty(num2)) { Toast.makeText(ClientActivity.this, "请输入第二个数字", Toast.LENGTH_LONG).show(); } else { if (iMyAidl != null) { try { int result = iMyAidl.add(Integer.valueOf(num1), Integer.valueOf(num2)); resultTv.setText(result + ""); } catch (RemoteException e) { e.printStackTrace(); } } } } }); } private void bindService() { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.aidl.tsnt.server", "com.aidl.tsnt.server.RemoteService")); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); unbindService(mServiceConnection); }}
对应的layout,activity_client.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_client" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".ClientActivity"> <EditText android:id="@+id/num1" android:layout_width="80dp" android:layout_height="wrap_content" android:gravity="center" android:hint="num1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+" /> <EditText android:id="@+id/num2" android:layout_width="80dp" android:layout_height="wrap_content" android:gravity="center" android:hint="num2" /> <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="=" /> <TextView android:id="@+id/result" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:textColor="@android:color/holo_red_dark" /></LinearLayout>
然后我们把server和client都运行起来,client调用远程server端的RemoteService就可以进行加法运算了:
4.传递自定义数据类型
AIDL支持Java的基本数据类型,还有String,CharSequence,List,Map和实现了Parcelable的自定义数据类型。当然这里所指的List和Map中的元素也必须是支持AIDL的数据类型。
下面就介绍一下在AIDL中如何传递自定义数据类型。
在sever中新建一个Dog类:
public class Dog implements Parcelable { int age; public Dog(int age) { this.age = age; } protected Dog(Parcel in) { age = in.readInt(); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static final Creator<Dog> CREATOR = new Creator<Dog>() { @Override public Dog createFromParcel(Parcel in) { return new Dog(in); } @Override public Dog[] newArray(int size) { return new Dog[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(age); }}
再新建一个aidl配置文件,文件名必须使用Dog,否则系统编译无法找到或者识别Dog。但是得注意到这里如果直接创建的话,会遇到一个错误提示:
Interface Name must be unique
需要我们先新建一个其他名字的xx.aidl,再将xx.aidl重命名为Dog.aidl,内容如下:
// Dog.aidlpackage com.aidl.tsnt.server;parcelable Dog;
然后修改IMyAidl.aidl:
// IMyAidl.aidlpackage com.aidl.tsnt.server;import com.aidl.tsnt.server.Dog;//导包不要忘记interface IMyAidl { int add(int num1,int num2); List<Dog> addDog(in Dog dog);//这里的in注意不要少}
然后重新build,修改RemoteService的内容:
public class RemoteService extends Service { private List<Dog> mDogs = new ArrayList<>(); Binder mBinder = new IMyAidl.Stub() { @Override public int add(int num1, int num2) throws RemoteException { return num1 + num2; } @Override public List<Dog> addDog(Dog dog) throws RemoteException { mDogs.add(dog); return mDogs; } }; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; }}
到这里server端已经修改完毕了,我们再看一下server的目录结构:
接下来是client端
1.将server目录下src/main下的aidl整个包复制粘贴到client下对应的位置,覆盖原来的文件
2.将server目录下src/main下的Dog文件以及它所在文件夹复制到client下对应的位置
然后重新build,修改client端中的逻辑:
public class ClientActivity extends AppCompatActivity { private IMyAidl iMyAidl; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iMyAidl = IMyAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { iMyAidl = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_client); initView(); bindService(); } private void initView() { final EditText num1Edt = (EditText) findViewById(R.id.num1); final EditText num2Edt = (EditText) findViewById(R.id.num2); Button addBtn = (Button) findViewById(R.id.add); final TextView resultTv = (TextView) findViewById(R.id.result); final TextView printTv = (TextView) findViewById(R.id.print); addBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String num1 = num1Edt.getText().toString().trim(); String num2 = num2Edt.getText().toString().trim(); if (TextUtils.isEmpty(num1)) { Toast.makeText(ClientActivity.this, "请输入第一个数字", Toast.LENGTH_LONG).show(); } else if (TextUtils.isEmpty(num2)) { Toast.makeText(ClientActivity.this, "请输入第二个数字", Toast.LENGTH_LONG).show(); } else { if (iMyAidl != null) { try { int result = iMyAidl.add(Integer.valueOf(num1), Integer.valueOf(num2));// resultTv.setText(result + ""); List<Dog> dogs = iMyAidl.addDog(new Dog(result)); StringBuffer buffer = new StringBuffer(); buffer.append("现在有"); for (int i = 0; i < dogs.size(); i++) { buffer.append(dogs.get(i).getAge() + "岁,"); } buffer.append("共" + dogs.size() + "只狗"); printTv.setText(buffer); } catch (RemoteException e) { e.printStackTrace(); } } } } }); } private void bindService() { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.aidl.tsnt.server", "com.aidl.tsnt.server.RemoteService")); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); unbindService(mServiceConnection); }}
还有对应的layout,activity_client.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_client" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".ClientActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/num1" android:layout_width="80dp" android:layout_height="wrap_content" android:gravity="center" android:hint="num1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+" /> <EditText android:id="@+id/num2" android:layout_width="80dp" android:layout_height="wrap_content" android:gravity="center" android:hint="num2" /> <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="=" /> <TextView android:id="@+id/result" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:textColor="@android:color/holo_red_dark" /> </LinearLayout> <TextView android:id="@+id/print" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginTop="10dp" /></LinearLayout>
最后运行client和server,如下图:
至此,AIDL实践完毕。
源码地址:https://github.com/tingshuonitiao/AIDL_practice
- AIDL最佳实践
- 最佳实践
- 最佳实践
- 最佳实践
- Android AIDL实践
- AIDL学习与实践
- AIDL实践二:自定义数据类型
- ANT十五大最佳实践
- C 编程最佳实践
- J2EE 最佳实践
- 【笔记】EJb最佳实践
- JUnit最佳实践
- ANT十五大最佳实践
- JUnit最佳实践
- ANT十五大最佳实践
- ANT十五大最佳实践
- ANT十五大最佳实践
- JUnit最佳实践
- popupwindow曾今遇到的坑
- 笔记——“Human-level control through deep reinforcement learning”
- sklearn通过OneVsRestClassifier实现svm.SVC的多分类
- spring boot 笔记(一):pom,注解
- storm两个案例(1单词计数本地执行 2累加集群执行 3集群关闭storm任务写法)
- AIDL最佳实践
- 从零开始学_JavaScript_系列(50)——Promise(3)全部完成all和看谁最快race
- Android中判断Wift是否开启,手机屏幕状态,sdcard是否被拔出,设置全屏
- 省市区三级联动jquery实现代码
- ad network 和 ad exchange 有什么区别?DSP ,SSP是什么?
- (四)代理模式
- COPY到目标源(EXCEL或WPS)丢失记录BUG及解决方法
- ./a.out: error while loading shared libraries: libfsdk.so: cannot open shared object file: No such f
- Listview Checkbox错乱问题