Android AIDL传递对象问题
来源:互联网 发布:天涯明月刀有mac版吗 编辑:程序博客网 时间:2024/06/08 17:21
前言
最近在研究aidl传递对象的时候,自己在网上搜了下,发现了不少问题。由于网上的资料有的对应的Android版本比较老,有的可能不适应现在的Android Studio的版本,一直有这样那样的问题。这里把我遇到的问题以及解决办法说明下。
步骤
服务端
- 首先我们先把新建一个aidl接口类
IMyAidlInterface
,在项目的app目录上右键new一个AIDL File,as会自动在main目录下创建一个aidl文件夹。 - 接着再新建一个AIDL File,
Person.aidl
。然后可以先rebuild
下工程。 - 接着在java的目录下,也就是与
MainActivity
同目录下新建一个类Person.java
并实现Parcelable
接口。 - 最后就是新建
Service
,命名为MyService
。
这里说一下,网上有些文章说是在aidl的目录下建Person.java,然后最后在gradle中把aidl目录配置为java源码目录。这个我试了,但是一直编译不过,找不到Person类。所以我就直接在默认的地方新建Person类,就没有问题了。
目录结构
代码
IMyAidlInterface.aidl
package com.limingjian.aidltest2;import com.limingjian.aidltest2.Person;interface IMyAidlInterface { int add(int a,int b); String inPerson(in Person p); String outPerson(out Person p); String inOutPerson(inout Person p);}
这里注意要把我们的Person
类的包手动导下。
Person.aidl
package com.limingjian.aidltest2;parcelable Person;
这里的parcelable,开头是小写的p
Person.java
package com.limingjian.aidltest2;import android.os.Parcel;import android.os.Parcelable;public class Person implements Parcelable { private String name; private int age; public Person() { } protected Person(Parcel in) { name = in.readString(); age = in.readInt(); } 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]; } }; 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; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } public void readFromParcel(Parcel dest) { name = dest.readString(); age = dest.readInt(); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; }}
MyService.java
package com.limingjian.aidltest2;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class MyService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("Log_LYL", "Onstart"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { Log.e("MyService", "onBind"); return stub; } IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() { @Override public int add(int a, int b) throws RemoteException { return a + b; } @Override public String inPerson(Person p) throws RemoteException { String old = "name:" + p.getName() + " age:" + p.getAge(); Log.d("Log_LYL:inPerson_", old); p.setName("李四"); p.setAge(13); return "name:" + p.getName() + " age:" + p.getAge(); } @Override public String outPerson(Person p) throws RemoteException { String old = "name:" + p.getName() + " age:" + p.getAge(); Log.d("Log_LYL:outPerson_", old); p.setName("周六"); p.setAge(20); return "name:" + p.getName() + " age:" + p.getAge(); } @Override public String inOutPerson(Person p) throws RemoteException { String old = "name:" + p.getName() + " age:" + p.getAge(); Log.d("Log_LYL:inOutPerson_", old); p.setName("弓七"); p.setAge(57); return "name:" + p.getName() + " age:" + p.getAge(); } };}
最后记得在AndroidManifest.xml文件里配置Service
<service android:name=".MyService" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.limingjian.aidl"/> </intent-filter> </service>
到这里,服务端就写好了。接下来是客户端。
客户端
我们新建个工程用来写客户端。
- 先把服务端的
aidl
目录直接拷贝到客户端的main
目录下,也就是与java
目录同级。 - 然后新建一个包,这里的包名要与服务端的
Person.java
所在的包名相同。然后把服务端的Person.java
拷贝到这个包里。
到这里aidl方面的工作就完成了。
目录结构
代码
activity_main.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_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="客户端" android:textColor="@android:color/holo_red_dark" android:textSize="15sp" /> <EditText android:id="@+id/et_num1" android:layout_width="200dp" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_num2" android:layout_width="200dp" android:layout_height="wrap_content" /> <Button android:id="@+id/bt_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加运算" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="结果:" /> <TextView android:id="@+id/tv" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" /> </LinearLayout></LinearLayout>
MainActivty.java
package com.limingjian.clienttest;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.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import com.limingjian.aidltest2.IMyAidlInterface;import com.limingjian.aidltest2.Person;public class MainActivity extends AppCompatActivity { private EditText et_num1, et_num2; private TextView tv; private IMyAidlInterface mService; private Button bt_add; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_num1 = (EditText) findViewById(R.id.et_num1); et_num2 = (EditText) findViewById(R.id.et_num2); bt_add = (Button) findViewById(R.id.bt_add); tv = (TextView) findViewById(R.id.tv); Intent intent = new Intent(); intent.setAction("com.limingjian.aidl"); //兼容Android 5.0以上 intent.setPackage("com.limingjian.aidltest2"); bindService(intent, mServiceC, Context.BIND_AUTO_CREATE); bt_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { add(); } }); } public void add() { int a = Integer.valueOf(et_num1.getText().toString()); int b = Integer.valueOf(et_num2.getText().toString()); try { int res = mService.add(a, b); tv.setText(res+""); Person p1 = new Person(); p1.setName("刘大"); p1.setAge(3); Person p2 = new Person(); p2.setName("赵二"); p2.setAge(3); Person p3 = new Person(); p3.setName("张三"); p3.setAge(3); tv.setText(res + "\n" + mService.inPerson(p1) + "\n" + mService.outPerson(p2) + "\n" + mService.inOutPerson(p3)+"\n" + p1.toString() + "\n" + p2.toString() + "\n" + p3.toString()); } catch (RemoteException e) { e.printStackTrace(); } } ServiceConnection mServiceC = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { mService = null; } }; @Override protected void onDestroy() { super.onDestroy(); unbindService(mServiceC); }}
从Android 5.0开始已经不能隐式启动Service
了,所以要加上intent.setPackage("com.limingjian.aidltest2")
,这里的包名就是服务端的MyService
所在的包的名字。
最后我们把服务端和客户端都部署到手机上。运行结果图如下
阅读全文
0 0
- Android AIDL传递对象问题
- Android使用AIDL传递对象
- AIDL传递parcelable对象找不到问题
- Android之AIDL示例(传递对象)
- Android--Service之AIDL传递复杂对象
- Android Service AIDL的学习,传递对象
- 学习笔记-Android AIDL传递对象数据
- Android AIDL 传递对象(Parceable)
- aidl 传递对象
- Aidl实现对象传递
- Android笔记三:Android 接口定义语言 (AIDL)--传递对象
- android之Service介绍之三 AIDL与传递对象
- android之Service介绍之三 AIDL与传递对象
- android之Service介绍之三 AIDL与传递对象
- android之Service介绍之三 AIDL与传递对象
- android之Service介绍之三 AIDL与传递对象
- Android进程间通信之----Aidl传递对象
- Android 使用AIDL跨进程通信(二)--传递自定义对象
- 利用webservice与后台通信
- android apk 安装过程
- spring properties
- invalid comparison: java.util.Date and java.lang.String异常的原因
- Vuex怎么学(二)
- Android AIDL传递对象问题
- Python socket编程(阻塞) --基于SocketServer
- Wireshark学习笔记——如何快速抓取HTTP数据包
- Kafka集群安装--测试--关闭
- css-----居中
- java设计模式(精通系列)-基础uml概念
- Java 按字节获得字符串(中文)长度
- 社交系统ThinkSNS-plus(TS+)V1.0发布!
- QTcpServer使用信号槽单线程方式直接处理连进来的客户端(短连接或少数据处理)