zoukankan      html  css  js  c++  java
  • 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句话就好了。

    • 到这里,Java bean算是真的准备好了,显示开始写你的需要被外界调用的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
  • 相关阅读:
    【Asp.Net从零开始】:上传文件(FileUpload)
    JavaScript变量声明及赋值
    427 类型数据
    427 自适应量化
    428 x264_reference_update
    427 expand_border
    426 pixel赋值问题 mbcmp函数 宏定义
    427 mb中一些参数记录备忘
    427 参考帧管理
    427 参数原来还有很多没有理解 比较详细的解释
  • 原文地址:https://www.cnblogs.com/jukan/p/7229127.html
Copyright © 2011-2022 走看看