当前位置:   article > 正文

Android ipc数据传输方式之一 AIDL_android aidl传递 string c++

android aidl传递 string c++

AIDL 的全名是 Android Interface definition language,就是一种在安卓的接口定义语言,而它的作用就是主要用于不同进程之间的通信

一 如何在AndroidStudio中创建AIDL?

首先要创建一个AIDL文件 AndroidStudio 穿件方式如下图:


第一次这样创建完成后就会出现一个aidl的文件夹

然后我们创建一个aidl文件 写完之后我们makeproject一下(最好先不要写实体类进去 等到下面实体类aidl步骤完成之后再回来写实体的相关导包 声明 方法等) 因为aidl默认传递的是String 加 基本数据类型

  1. // IMyAidlInterface.aidl
  2. package com.example.lyl.aidldemo;
  3. import com.example.lyl.aidldemo.UserBean;//一定要导入实体类的包!
  4. // Declare any non-default types here with import statements
  5. interface IMyAidlInterface {
  6. /**
  7. * Demonstrates some basic types that you can use as parameters
  8. * and return values in AIDL.
  9. */
  10. // void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
  11. // double aDouble, String aString);
  12. int add (int a , int b);
  13. void sendUrl(String url);
  14. //传递其他数据类型的时候前面要加上in 代表这个数据要往服务里传
  15. void sendUser (in UserBean userBean);
  16. }

我们定义一个加法和字符串传输方法,还有一个传递实体类的方法  

注意:

sendUser方法中 实体类前面的in是定向tag,定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数值,分为 in、out、inout 三种。其中 in 表示数据只能由客户端流向服务端, out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。此外,如果AIDL方法接口的参数值类型是:基本数据类型、String、CharSequence或者其他AIDL文件定义的方法接口,那么这些参数值的定向 Tag 默认是且只能是 in,所以除了这些类型外,其他参数值都需要明确标注使用哪种定向Tag。


如果我们要传递实体类该怎么办呢?

我们先创建一个实体类并将它包裹化

  1. public class UserBean implements Parcelable {
  2. private int id;
  3. private String password;
  4. public UserBean() {
  5. }
  6. protected UserBean(Parcel in) {
  7. id = in.readInt();
  8. password = in.readString();
  9. }
  10. public static final Creator<UserBean> CREATOR = new Creator<UserBean>() {
  11. @Override
  12. public UserBean createFromParcel(Parcel in) {
  13. return new UserBean(in);
  14. }
  15. @Override
  16. public UserBean[] newArray(int size) {
  17. return new UserBean[size];
  18. }
  19. };
  20. @Override
  21. public String toString() {
  22. return "UserBean{" +
  23. "id=" + id +
  24. ", password='" + password + '\'' +
  25. '}';
  26. }
  27. public int getId() {
  28. return id;
  29. }
  30. public void setId(int id) {
  31. this.id = id;
  32. }
  33. public String getPassword() {
  34. return password;
  35. }
  36. public void setPassword(String password) {
  37. this.password = password;
  38. }
  39. @Override
  40. public int describeContents() {
  41. return 0;
  42. }
  43. @Override
  44. public void writeToParcel(Parcel dest, int flags) {
  45. dest.writeInt(id);
  46. dest.writeString(password);
  47. }
  48. }

在定义一个aidl 这个aidl的名字需要和实体类的名字一样

  1. // UserBean1.aidl
  2. package com.example.lyl.aidldemo;
  3. parcelable UserBean;
这个实体类的aidl中 需要把类进行包裹化声明 完成以上步骤就可以数据传递了


二 如何利用aidl在activity进程和service进程中进行数据传递

然后要创建一个新的进程 创建一个Service 并在manifest 清单文件中进行声明:

 <service android:name=".AidlServer" android:process=":aidl"/>
pricess属性是让这个组件运行在不同于APP进程的另一个新进程 并给这个进程起一个名字

然后创建这个服务并绑定

  1. public class AidlServer extends Service {
  2. @Nullable
  3. @Override
  4. public IBinder onBind(Intent intent) {
  5. return new ServiceBinder();
  6. }
  7. public class ServiceBinder extends IMyAidlInterface.Stub{
  8. @Override
  9. public int add(int a, int b) throws RemoteException {
  10. int i2 = Process.myPid();//获取该进程的ID。
  11. Log.d("MainActivity", "Service进程id:" + i2);
  12. int i3 = Process.myTid();//获取该线程的ID。
  13. Log.d("MainActivity", "Service线程id:" + i3);
  14. return a+b;
  15. }
  16. @Override
  17. public void sendUrl(String url) throws RemoteException {
  18. int i2 = Process.myPid();//获取该进程的ID。
  19. Log.d("MainActivity", "Service进程id:" + i2);
  20. int i3 = Process.myTid();//获取该线程的ID。
  21. Log.d("MainActivity", "Service线程id:" + i3);
  22. Log.d("ServiceBinder", url);
  23. }
  24. @Override
  25. public void sendUser(UserBean userBean) throws RemoteException {
  26. int i2 = Process.myPid();//获取该进程的ID。
  27. Log.d("MainActivity", "Service进程id:" + i2);
  28. int i3 = Process.myTid();//获取该线程的ID。
  29. Log.d("MainActivity", "Service线程id:" + i3);
  30. Log.d("ServiceBinder", "userBean:" + userBean);
  31. }
  32. }
  33. }

我们可以看到 我们单进程中使用service时 一般都继承一个binder类 但是为了要在Service中实现我们再Aidl中声明的方法,

所以我们需要继承IMyAidlInterface.Stub 这个类

这样我们在服务中就可以接收到Activity进程中的网址 我们就可以在一个新的进程中做下载操作

最后我们只需要在Acitivity中用bindservice 绑定服务 就可以了

Activity的布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. xmlns:tools="http://schemas.android.com/tools"
  6. android:layout_width="match_parent"
  7. android:layout_height="match_parent"
  8. tools:context="com.example.lyl.aidldemo.MainActivity">
  9. <Button
  10. android:id="@+id/btn_bind"
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"
  13. android:text="绑定服务" />
  14. <Button
  15. android:id="@+id/btn_control"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:text="控制服务" />
  19. <Button
  20. android:id="@+id/btn_change"
  21. android:layout_width="wrap_content"
  22. android:layout_height="wrap_content"
  23. android:text="传值" />
  24. </LinearLayout>

Activity中的代码

  1. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  2. private Button btn_bind;
  3. private Button btn_control;
  4. private Button btn_change;
  5. private IMyAidlInterface iMyAidlInterface;
  6. private ServiceConnection serviceConnection = new ServiceConnection() {
  7. @Override
  8. public void onServiceConnected(ComponentName name, IBinder service) {
  9. iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
  10. }
  11. @Override
  12. public void onServiceDisconnected(ComponentName name) {
  13. }
  14. };
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. initView();
  20. }
  21. private void initView() {
  22. btn_bind = (Button) findViewById(R.id.btn_bind);
  23. btn_control = (Button) findViewById(R.id.btn_control);
  24. btn_change = (Button) findViewById(R.id.btn_change);
  25. btn_bind.setOnClickListener(this);
  26. btn_control.setOnClickListener(this);
  27. btn_change.setOnClickListener(this);
  28. }
  29. @Override
  30. public void onClick(View v) {
  31. switch (v.getId()) {
  32. case R.id.btn_bind:
  33. Intent intentAidl = new Intent(MainActivity.this,AidlServer.class);
  34. bindService(intentAidl,serviceConnection,BIND_AUTO_CREATE);
  35. break;
  36. case R.id.btn_control:
  37. int i = Process.myPid();//获取该进程的ID。
  38. Log.d("MainActivity", "Activity进程id:" + i);
  39. int i1 = Process.myTid();//获取该线程的ID。
  40. Log.d("MainActivity", "Activity线程id:" + i1);
  41. try {
  42. iMyAidlInterface.sendUrl("https://www.baidu.com");
  43. UserBean userBean = new UserBean();
  44. userBean.setId(1);
  45. userBean.setPassword("123");
  46. iMyAidlInterface.sendUser(userBean);
  47. } catch (RemoteException e) {
  48. e.printStackTrace();
  49. }
  50. break;
  51. case R.id.btn_change:
  52. int i2 = Process.myPid();//获取该进程的ID。
  53. Log.d("MainActivity", "Activity进程id:" + i2);
  54. int i3 = Process.myTid();//获取该线程的ID。
  55. Log.d("MainActivity", "Activity线程id:" + i3);
  56. try {
  57. int add = iMyAidlInterface.add(5, 8);
  58. Log.d("MainActivity", "add:" + add);
  59. } catch (RemoteException e) {
  60. e.printStackTrace();
  61. }
  62. break;
  63. }
  64. }
  65. }




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/245318
推荐阅读
相关标签
  

闽ICP备14008679号