Android ipc数据传输方式之一 AIDL
2018-02-03 15:47
525 查看
AIDL 的全名是 Android
Interface definition language,就是一种在安卓的接口定义语言,而它的作用就是主要用于不同进程之间的通信
第一次这样创建完成后就会出现一个aidl的文件夹
然后我们创建一个aidl文件 写完之后我们makeproject一下(最好先不要写实体类进去 等到下面实体类aidl步骤完成之后再回来写实体的相关导包
声明 方法等) 因为aidl默认传递的是String 加 基本数据类型
我们定义一个加法和字符串传输方法,还有一个传递实体类的方法
注意:
sendUser方法中 实体类前面的in是定向tag,定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数值,分为
in、out、inout 三种。其中 in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。此外,如果AIDL方法接口的参数值类型是:基本数据类型、String、CharSequence或者其他AIDL文件定义的方法接口,那么这些参数值的定向 Tag 默认是且只能是 in,所以除了这些类型外,其他参数值都需要明确标注使用哪种定向Tag。
如果我们要传递实体类该怎么办呢?
我们先创建一个实体类并将它包裹化
在定义一个aidl 这个aidl的名字需要和实体类的名字一样
二 如何利用aidl在activity进程和service进程中进行数据传递
然后要创建一个新的进程 创建一个Service 并在manifest 清单文件中进行声明:
然后创建这个服务并绑定
我们可以看到 我们单进程中使用service时 一般都继承一个binder类 但是为了要在Service中实现我们再Aidl中声明的方法,
所以我们需要继承IMyAidlInterface.Stub
这个类
这样我们在服务中就可以接收到Activity进程中的网址 我们就可以在一个新的进程中做下载操作
最后我们只需要在Acitivity中用bindservice 绑定服务 就可以了
Activity的布局文件:
Activity中的代码
Interface definition language,就是一种在安卓的接口定义语言,而它的作用就是主要用于不同进程之间的通信
一 如何在AndroidStudio中创建AIDL?
首先要创建一个AIDL文件 AndroidStudio 穿件方式如下图:第一次这样创建完成后就会出现一个aidl的文件夹
然后我们创建一个aidl文件 写完之后我们makeproject一下(最好先不要写实体类进去 等到下面实体类aidl步骤完成之后再回来写实体的相关导包
声明 方法等) 因为aidl默认传递的是String 加 基本数据类型
// IMyAidlInterface.aidl package com.example.lyl.aidldemo; import com.example.lyl.aidldemo.UserBean;//一定要导入实体类的包! // Declare any non-default types here with import statements interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ // void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, // double aDouble, String aString); int add (int a , int b); void sendUrl(String url); //传递其他数据类型的时候前面要加上in 代表这个数据要往服务里传 void sendUser (in UserBean userBean); }
我们定义一个加法和字符串传输方法,还有一个传递实体类的方法
注意:
sendUser方法中 实体类前面的in是定向tag,定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数值,分为
in、out、inout 三种。其中 in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。此外,如果AIDL方法接口的参数值类型是:基本数据类型、String、CharSequence或者其他AIDL文件定义的方法接口,那么这些参数值的定向 Tag 默认是且只能是 in,所以除了这些类型外,其他参数值都需要明确标注使用哪种定向Tag。
如果我们要传递实体类该怎么办呢?
我们先创建一个实体类并将它包裹化
public class UserBean implements Parcelable { private int id; private S 4000 tring password; public UserBean() { } protected UserBean(Parcel in) { id = in.readInt(); password = in.readString(); } public static final Creator<UserBean> CREATOR = new Creator<UserBean>() { @Override public UserBean createFromParcel(Parcel in) { return new UserBean(in); } @Override public UserBean[] newArray(int size) { return new UserBean[size]; } }; @Override public String toString() { return "UserBean{" + "id=" + id + ", password='" + password + '\'' + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeString(password); } }
在定义一个aidl 这个aidl的名字需要和实体类的名字一样
// UserBean1.aidl package com.example.lyl.aidldemo; parcelable UserBean;这个实体类的aidl中 需要把类进行包裹化声明 完成以上步骤就可以数据传递了
二 如何利用aidl在activity进程和service进程中进行数据传递
然后要创建一个新的进程 创建一个Service 并在manifest 清单文件中进行声明:
<service android:name=".AidlServer" android:process=":aidl"/>pricess属性是让这个组件运行在不同于APP进程的另一个新进程 并给这个进程起一个名字
然后创建这个服务并绑定
public class AidlServer extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return new ServiceBinder(); } public class ServiceBinder extends IMyAidlInterface.Stub{ @Override public int add(int a, int b) throws RemoteException { int i2 = Process.myPid();//获取该进程的ID。 Log.d("MainActivity", "Service进程id:" + i2); int i3 = Process.myTid();//获取该线程的ID。 Log.d("MainActivity", "Service线程id:" + i3); return a+b; } @Override public void sendUrl(String url) throws RemoteException { int i2 = Process.myPid();//获取该进程的ID。 Log.d("MainActivity", "Service进程id:" + i2); int i3 = Process.myTid();//获取该线程的ID。 Log.d("MainActivity", "Service线程id:" + i3); Log.d("ServiceBinder", url); } @Override public void sendUser(UserBean userBean) throws RemoteException { int i2 = Process.myPid();//获取该进程的ID。 Log.d("MainActivity", "Service进程id:" + i2); int i3 = Process.myTid();//获取该线程的ID。 Log.d("MainActivity", "Service线程id:" + i3); Log.d("ServiceBinder", "userBean:" + userBean); } } }
我们可以看到 我们单进程中使用service时 一般都继承一个binder类 但是为了要在Service中实现我们再Aidl中声明的方法,
所以我们需要继承IMyAidlInterface.Stub
这个类
这样我们在服务中就可以接收到Activity进程中的网址 我们就可以在一个新的进程中做下载操作
最后我们只需要在Acitivity中用bindservice 绑定服务 就可以了
Activity的布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.lyl.aidldemo.MainActivity"> <Button android:id="@+id/btn_bind" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="绑定服务" /> <Button android:id="@+id/btn_control" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="控制服务" /> <Button android:id="@+id/btn_change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="传值" /> </LinearLayout>
Activity中的代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btn_bind; private Button btn_control; private Button btn_change; private IMyAidlInterface iMyAidlInterface; private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { btn_bind = (Button) findViewById(R.id.btn_bind); btn_control = (Button) findViewById(R.id.btn_control); btn_change = (Button) findViewById(R.id.btn_change); btn_bind.setOnClickListener(this); btn_control.setOnClickListener(this); btn_change.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_bind: Intent intentAidl = new Intent(MainActivity.this,AidlServer.class); bindService(intentAidl,serviceConnection,BIND_AUTO_CREATE); break; case R.id.btn_control: int i = Process.myPid();//获取该进程的ID。 Log.d("MainActivity", "Activity进程id:" + i); int i1 = Process.myTid();//获取该线程的ID。 Log.d("MainActivity", "Activity线程id:" + i1); try { iMyAidlInterface.sendUrl("https://www.baidu.com"); UserBean userBean = new UserBean(); userBean.setId(1); userBean.setPassword("123"); iMyAidlInterface.sendUser(userBean); } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.btn_change: int i2 = Process.myPid();//获取该进程的ID。 Log.d("MainActivity", "Activity进程id:" + i2); int i3 = Process.myTid();//获取该线程的ID。 Log.d("MainActivity", "Activity线程id:" + i3); try { int add = iMyAidlInterface.add(5, 8); Log.d("MainActivity", "add:" + add); } catch (RemoteException e) { e.printStackTrace(); } break; } } }
相关文章推荐
- Android 数据传输方式 WIFI 蓝牙 USB
- 一篇文章读懂Android组件之间数据传递方法 IPC进程通信方法AIDL介绍
- Android中的IPC方式(二)—— AIDL
- 【Android数据加密与完整性校验之使用MessageDigest类进行MD5/SHA1】校验数据传输的完整性常用方式
- Android ipc数据传递方式之二 Messenger 信使
- android网络编程之json传输数据以及解析方式
- android网络访问post方式(数据传输采用json数据流,非参数传递)
- 9.Android中的IPC方式——Bundle、文件共享、Messenger、AIDL、Content-Provider
- IPC机制系列之三 Android中的IPC方式 (AIDL)
- Android中的IPC——AIDL方式
- android AIDL中数据的传输
- Android中进程间通讯(IPC)方式之一AIDL机制
- Android中的IPC方式——使用AIDL
- Android开发--Udp方式的数据传输
- Android中的IPC方式AIDL
- Android客户端向Python服务器以POST方式传输数据
- Android数据的四种存储方式
- android使用MultipartEntity传输表单数据的问题
- Android中的5种数据存储方式
- Android几种数据存储方式的应用场景