AndroidStudio 使用AIDL

http://blog.csdn.net/ducklikejava/article/details/51559244

  • Android Studio中写的一个AIDL的小DEMO.
  • 步骤很繁琐,本来不准备写的。但是写一下是为了记录,这一下午终于跑通了这玩意。
  • 首先,你要有3个 Module,至少两个,但是最好是3个 
    • 一个是你的AIDL文件与它的Service所在的Module
    • 一个是你的客户端Module,也就是你真正调用AIDLModule
    • 最后一个是你的AIDL需要使用的Parcelable对象存放的Module.如果你要传递的只是基本的数据类型,那么这一项可以不要。如果你直接将该对象创建在你的调用AIDLModule中,这一项也可以不要。
    • 为什么我说要3个Module呢? 
      • 因为:第三个Module是作为第一个和第二个的共同依赖存在的。这样,两边都可以使用其中的 对象。
  • 然后,你得先有一个Service,这个Service就是你的AIDL的具体实现。你的AIDL想要什么功能,完全取决于你的service怎么写了。
    • package com.pythoncat.aidl_libiary;
      
      import android.app.Service;
      import android.content.Intent;
      
      public class HelloService extends Service {
          public HelloService() {
          }
          @Nullable
          @Override
          public IBinder onBind(Intent intent) {
              return null;
          }
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
  • 好了,你的Service已经有了。但是目前还没有什么意义。为了将这个AIDL做得有意思一点,我们假设你是要通过AIDL传递复杂的数据,比如Student这样类似的一个java bean
  • 既然这样,那么,我们就需要一个Student类了,注意:必须实现Parcelable,不如就不能AIDL了。差不多这个类就长这样:
    package com.pythoncat.core.model;

    import android.os.Parcel;
    import android.os.Parcelable;

    /**
     * Created by pythonCat on 2016/6/1.
     */
    public class Student implements Parcelable {

        public String name;
        public int age;
        public int sex;

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(this.name);
            dest.writeInt(this.age);
            dest.writeInt(this.sex);
        }

        public Student() {
        }

        protected Student(Parcel in) {
            this.name = in.readString();
            this.age = in.readInt();
            this.sex = in.readInt();
        }

        public static final Creator<Student> CREATOR = new Creator<Student>() {
            @Override
            public Student createFromParcel(Parcel source) {
                return new Student(source);
            }

            @Override
            public Student[] newArray(int size) {
                return new Student[size];
            }
        };
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 好了,你的Student已经准备好了,现在就是真的要定义一下AIDL文件了。因为这个Student是要通过AIDL去传递的,所以这个Student也要成为一个AIDL.

这句话听起来比较费解,是因为我表达的不够好。其实说白了,就是要多创建一个名为Student.aidl的文件,这个文件差不多这样:

    // Student.aidl
    package com.pythoncat.core.model;
    parcelable Student;
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

注意了:这个文件所在目录,必须是在一个aidl目录下,创建一个和Student.Java同包名的包。比如,我的Student.java是在package com.pythoncat.core.model;中,那么,我就要在AIDL所在Module中,创建一个aidl目录,然后在该目录下创建一个package,package名字就是package com.pythoncat.core.model。最后,在该package下,创建一个Student.aidl文件,里面就写上面3句话就好了。

  • 到这里,Javabean算是真的准备好了,显示开始写你的需要被外界调用的AIDL了。这个文件位置随便写,你就在java目录下创建一个.aidl文件好了。文件名假设是IHelloInterface,文件假设是这样的:
```
// IHelloInterface.aidl
package com.pythoncat.aidl_libiary;

import com.pythoncat.core.model.Student;
// Declare any non-default types here with import statements

interface IHelloInterface {
    /**
     * 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);

    String hello();

    Student getOne();
}
```

注意一下,上面有一个import com.pythoncat.core.model.Student;就是刚才的那个Student.aidl的导入。、

    • ok,到了这里。已经完成了一小半了。然后是,build -> make project (ctrl+F9)一下。让android studio帮你一把。
    • build -> make project (ctrl+F9)之后,你会看到你的IHelloInterface .aidl自动跑到aidl目录里面去了。不过这个都不是我关心的。
    • 现在,我们完善我们的HelloService:
      package com.pythoncat.aidl_libiary;
      
      import android.app.Service;
      import android.content.Intent;
      import android.os.IBinder;
      import android.os.RemoteException;
      import android.support.annotation.Nullable;
      
      import com.pythoncat.core.model.Student;
      
      /**
       * <action android:name="com.pythoncat.aidl_libiary.HelloService"/>
       * <hr/>
       * package="com.pythoncat.aidl_libiary"
       */
      public class HelloService extends Service {
          public HelloService() {
          }
      
          @Nullable
          @Override
          public IBinder onBind(Intent intent) {
              return new MyBinder();
          }
      
          class MyBinder extends IHelloInterface.Stub {
      
              @Override
              public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
      
              }
      
              @Override
              public String hello() throws RemoteException {
                  return "Just Hello World";
              }
      
              @Override
              public Student getOne() throws RemoteException {
                  return new Student();
              }
          }
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
    • 发现没有,现在我们的Service,AIDL,Model已经关联起来了,接下来就是调用者的事情了。
    • ** 既然是调用者的事情了,那我们就搞一个Activity去调用试试吧。
    • 在调用处,其实和平常的绑定服务几乎没有任何的差别,都是通过ServiceConnection去获取接口的引用,然后就可以调用接口里面的方法了。[接口的实现,已经在我们的HelloService里面搞定了]。
    • 调用就一个Activity里面一个按钮的点击事件 ,布局文件就不写了,没什么意义。那么调用者差不多这样的:
      package com.pythoncat.helloaidl;
      
      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 com.apkfuns.logutils.LogUtils;
      import com.github.johnpersano.supertoasts.SuperToast;
      import com.pythoncat.aidl_libiary.IHelloInterface;
      import com.pythoncat.core.model.Student;
      
      public class MainActivity extends AppCompatActivity {
      
          private IHelloInterface iService;
          private ServiceConnection conn = new ServiceConnection() {
              @Override
              public void onServiceConnected(ComponentName name, IBinder service) {
                  iService = IHelloInterface.Stub.asInterface(service);
                  try {
                      final String hello = iService.hello();
                      LogUtils.e("hello::::::::" + hello);
                      final Student one = iService.getOne();
                      LogUtils.e(one);
                      runOnUiThread(new Runnable() {
                          @Override
                          public void run() {
                              SuperToast.cancelAllSuperToasts();
                              SuperToast.create(getApplicationContext(), hello, SuperToast.Duration.MEDIUM).show();
                          }
                      });
                  } catch (RemoteException e) {
                      e.printStackTrace();
                  }
              }
      
              @Override
              public void onServiceDisconnected(ComponentName name) {
                  iService = null;
                  LogUtils.e("iService::::::::" + iService);
              }
          };
          private boolean bindService;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
          }
      
          @Override
          protected void onStart() {
              super.onStart();
              final Intent in = new Intent();
              in.setClassName(this, "com.pythoncat.aidl_libiary.HelloService");
              in.setPackage("com.pythoncat.aidl_libiary");
              in.setAction("com.pythoncat.aidl_libiary.HelloService");
              bindService = bindService(in, conn, Context.BIND_AUTO_CREATE);
              LogUtils.e("bindService=" + bindService);
          }
      
          @Override
          protected void onStop() {
              super.onStop();
              if (conn != null) {
                  unbindService(conn);
              }
          }
      
          public void clickButton(View v) {
              LogUtils.e("bindService=" + bindService);
              LogUtils.e(iService);
              if (iService == null) {
                  SuperToast.cancelAllSuperToasts();
                  SuperToast.create(getApplicationContext(), iService + "", SuperToast.Duration.MEDIUM).show();
              } else {
                  SuperToast.cancelAllSuperToasts();
                  try {
                      SuperToast.create(getApplicationContext(), iService.hello(), SuperToast.Duration.MEDIUM).show();
                  } catch (RemoteException e) {
                      e.printStackTrace();
                  }
              }
      
          }
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
    • 这样,其实就已经完成了一个AIDL的调用的整个过程。
    • 另外,一旦项目跑不通,多弄几次build -> make project (ctrl+F9)的操作,还是跑不通,就是代码有问题了。 

      不过,我必须坦白的是,我的调用者的Module还是引用了AIDL所在Module。因为我不引用就不能成功绑定远程服务。这个问题应该是可以解决的,以后解决了,再记录到这边来。

    • 项目戳我,戳我啊~…~
    • 真的彩蛋后续更新FINAL
时间: 2024-08-04 11:42:17

AndroidStudio 使用AIDL的相关文章

AndroidStudio通过AIDL开启、绑定远程Service

前言 关于服务的启动方式(startService().stopService().bindService().unbindService()),我这里就不多说了,可以参考这篇博文. 示例原理图 本文以一个简单的案例,记录一下怎么使用AIDL结合服务实现进程间的通信: 首先,创建两个项目,一个项目(RemoteService)作为远程服务提供端,另一个(RemoteServiceTest)作为调用远程服务的客户端.然后,当客户端绑定远程服务后,可以通过AIDL接口调用远程服务中的方法,原理过程如

AndroidStudio实现AIDL

AIDL的使用步骤 aidl远程调用传递的参数和返回值支持Java的基本类型(int long booen char byte等)和String,List,Map等.当然也支持一个自定义对象的传递. 服务端 新建一个MyAidlDemoServer工程,然后在main目录下右键新建一个aidl目录,然后在该目录下新建一个IMyAidlInterface.aidl文件,代码如下: 1 interface IMyAidlInterface { 2 3 int add(int arg1, int ar

AndroidStudio通过AIDL开启 绑定远程Service

转载 示例原理图 本文以一个简单的案例,记录一下怎么使用AIDL结合服务实现进程间的通信: 首先,创建两个项目,一个项目(RemoteService)作为远程服务提供端,另一个(RemoteServiceTest)作为调用远程服务的客户端.然后,当客户端绑定远程服务后,可以通过AIDL接口调用远程服务中的方法,原理过程如图: 远程服务RemoteService 项目 1.创建AIDL文件,选中要提供的服务类所在的包名,右键 -> New -> AIDL -> AIDL File文件,如图

Android Studio创建AIDL文件并实现进程间通讯

在Android系统中,跨进程通信是非常普遍的事情,它用到了Binder机制处理进程之间的交互.Binder机制会开放一些接口给java层,供android开发工程师调用进程之间通信.这些接口android封装到了AIDL文件里,当我们项目用到跨进程通信时可以创建.aidl文件,.aidl文件可以协助我们达到跨进程的通信.下面简单介绍用AndroidStudio创建AIDL文件的过程. a.新建AIDL文件 1.项目文件夹右键---> new --->选择AIDL 2.自定义一个接口名称 3.

Android Service的全面解析

Service基本用法 基本用法即同进程下Activity与Service双向通信,先描述整体实现过程然后直接上代码: 新建一个继承自Service的类MyService,然后在AndroidManifest.xml里注册这个Service Activity里面使用bindService方式启动MyService,也就是绑定了MyService(到这里实现了绑定,Activity与Service通信的话继续下面的步骤) 新建一个继承自Binder的类MyBinder 在MyService里实例化

[Android Pro] AndroidStudio导出jar包

reference :  http://blog.csdn.net/beijingshi1/article/details/38681281 不像在Eclipse,可以直接导出jar包.AndroidStudio只可以生成aar包. 在网上看到许多朋友问怎么可以像Eclipse一样导出jar包,其实我们只要知道它的原理就可以了. 用jar命令就可以打包你所需要的资源,并指定jar包名. 在网上下载Volley源代码,导出jar包为例子. 在Volley项目工程中,我修改了下他的gradle版本,

android的AIDL

一.AIDL的意义:           AIDL全称是Android Interface Definition Language,是android接口定义语言.AIDL就是为了避免我们一遍遍的写一些千篇一律的代码而出现的一个模板. 目的:实现进程间通信,而且在能在多进程并发的情况下进行进程间的通信. 与Messenger的区别: Messenger 是以串行的方式处理客户端发来的消息,如果有大量的并发请求那么Messenger就不大适合这些情况了,同时Messenger的作用主要是为了传递消息

AndroidStudio学习记录

AndroidStudio学习记录 1. 插件的使用. plugins.jetbrains.com插件网站. 2. 目录介绍: 1.Studio中有Project和Module的概念,前面说到Studio中一个窗口只能有一个项目,即Project,代表一个workspace,但是一个Project可以包含多个Module,比如你项目引用的Android Library, Java Library等,这些都可以看做是一个Module; 2.上述目录中将java代码和资源文件(图片.布局文件等)全部

Android的IPC机制(一)——AIDL的使用

综述 IPC(interprocess communication)是指进程间通信,也就是在两个进程间进行数据交互.不同的操作系统都有他们自己的一套IPC机制.例如在Linux操作系统中可以通过管道.信号量.消息队列.内存共享.套接字等进行进程间通信.那么在Android系统中我们可以通过Binder来进行进程间的通信.当然除了Binder我们还可以使用Socket来进行进程间的通信.  既然需要进程通信,那么就必须有多个进程.当然,在两个应用交互中必然出现多进程的情况.若是在一个应用中呢?我们