Binder service入门—应用层binder service

http://www.cloudchou.com/android/post-458.html


Binder service入门—应用层binder service

1.前言

Binder service入门系列:

上一篇介绍了Framework Binder Service,本篇将介绍如何创建应用层的binder service。 实际上在应用层使用binder service时,并没有直接与ServiceManager交互(应用层不能直接使用ServiceManager 类),一般是在Service子类里覆盖onBind方法,返回新创建的Binder实体对象。应用层使用Activity作为binder service的客户端,在Activity里创建ServiceConnecttion对象,并调用bindService方法绑定service,在ServiceConnection的onServiceConnected方法将接收到的IBinder对象转化为接口对象,然后再通过这个接口对象调用binder service的接口方法。

2.程序构成

程序在应用开发环境下编译。

整个工程可以在github上下载: https://github.com/cloudchou/AndroidBinderTest

本示例使用remote service,声明service时,使用了android:process属性。

3.程序源码构成

源代码结构如下所示:

app_f

AndroidManifeset.xml:声明用到的activity,service组件

ICloudManager.aidl: binder service接口

CloudService: 创建binder service,并返回给客户端

TestAc: 测试binder service的客户端

实现应用层 binder service的步骤

  • 1) 使用aidl定义binder service接口ICloudManager
    1
    2
    3
    4
    5
    
    package com.cloud.test;
    interface ICloudManager{
        void print(String str) ;
        int add(int a, int b);
    }

    aidl全称是android interface definition language,用于定义binder service接口,语法与Java的接口非常类似,详情可参考:http://developer.android.com/guide/components/aidl.html

    使用eclipse开发时,它会被自动编译成ICloudManager.java,放在gen目录下。生成的ICloudManager.java源码如下所示:

    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
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    
    //声明接口ICloudManager 继承自IInterface,这里和在Framework使用binder service类似
    public interface ICloudManager extends android.os.IInterface {
        /**binder service实体类和framework的binder service实体类类似 */
        public static abstract class Stub extends android.os.Binder implements com.cloud.test.ICloudManager {
            private static final java.lang.String DESCRIPTOR = "com.cloud.test.ICloudManager";
     
            /** Construct the stub at attach it to the interface. */
            public Stub() {
                this.attachInterface(this, DESCRIPTOR);
            }
     
            /**
             * Cast an IBinder object into an com.cloud.test.ICloudManager interface, generating a proxy if needed.
             */
            public static com.cloud.test.ICloudManager asInterface(android.os.IBinder obj) {
                if ((obj == null)) {
                    return null;
                }
                android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
                if (((iin != null) && (iin instanceof com.cloud.test.ICloudManager))) {
                    return ((com.cloud.test.ICloudManager) iin);
                }
                return new com.cloud.test.ICloudManager.Stub.Proxy(obj);
            }
     
            @Override
            public android.os.IBinder asBinder() {
                return this;
            }
     
            @Override
            public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
                    throws android.os.RemoteException {
                switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(DESCRIPTOR);
                    return true;
                }
                case TRANSACTION_print: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    this.print(_arg0);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_add: {
                    data.enforceInterface(DESCRIPTOR);
                    int _arg0;
                    _arg0 = data.readInt();
                    int _arg1;
                    _arg1 = data.readInt();
                    int _result = this.add(_arg0, _arg1);
                    reply.writeNoException();
                    reply.writeInt(_result);
                    return true;
                }
                }
                return super.onTransact(code, data, reply, flags);
            }
     
            //binder service的引用类,或者说是代理,和framework使用binder service类似
            private static class Proxy implements com.cloud.test.ICloudManager {
                private android.os.IBinder mRemote;
     
                Proxy(android.os.IBinder remote) {
                    mRemote = remote;
                }
     
                @Override
                public android.os.IBinder asBinder() {
                    return mRemote;
                }
     
                public java.lang.String getInterfaceDescriptor() {
                    return DESCRIPTOR;
                }
     
                @Override
                public void print(java.lang.String str) throws android.os.RemoteException {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeString(str);
                        mRemote.transact(Stub.TRANSACTION_print, _data, _reply, 0);
                        _reply.readException();
                    } finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                }
     
                @Override
                public int add(int a, int b) throws android.os.RemoteException {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    int _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(a);
                        _data.writeInt(b);
                        mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
                        _reply.readException();
                        _result = _reply.readInt();
                    } finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
            }
     
            static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
            static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        }
     
        public void print(java.lang.String str) throws android.os.RemoteException;
     
        public int add(int a, int b) throws android.os.RemoteException;
    }

    由此可见应用层使用binder service实际上和framework使用binder service是非常类似的,只是在应用层使用binder service时,只需编写aidl,开发工具可帮我们自动编译生成java源码文件,该源文件里包含接口,binder service实体类(抽象类,接口方法还未实现),binder service引用类的源码。

  • 2) 实现Service
    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
    
    public class CloudService extends Service {
      private final static String TAG = CloudService.class.getSimpleName();
     
      //实现binder service实体类
      class CloudMananger extends ICloudManager.Stub {
     
          @Override
          public void print(String str) throws RemoteException {
              Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() 
                         + "] [ProcessId" + Process.myPid()
                         + "]CloudService receive client print msg request: " 
                         + str);
          }
     
          @Override
          public int add(int a, int b) throws RemoteException {
              Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() 
                          + "] [ProcessId" + Process.myPid()
                          + "[CloudService receive client add request : ");
              return a + b;
          }
      }
     
      @Override
      public void onCreate() {
          super.onCreate();
          Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() 
                     + "] [ProcessId" + Process.myPid() + "]  onCreate");
      }
     
     //定义binder service实体类对象
      private CloudMananger manager = new CloudMananger();
     
     //覆盖onBind方法,返回binder service实体类对象
      @Override
      public IBinder onBind(Intent intent) {
          Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() 
                     + "] [ProcessId" + Process.myPid() + "]  onBind");
          return manager;
      }
     
    }
  • 3) 实现Client
    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
    
    public class TestAc extends Activity {
        private static final String TAG = TestAc.class.getSimpleName();
        private ICloudManager manager = null;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() 
                        + "] [ProcessId" + Process.myPid() + "]  onCreate");
            findViewById(R.id.btn_print).setOnClickListener(
               new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        Log.d(TAG, "=========== Client call "
                                   +"CloudService print function");
                        //调用print方法
                        manager.print("Hello world");
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
            findViewById(R.id.btn_add).setOnClickListener(
                new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        Log.d(TAG, "======Client call "
                                   +"CloudService add function");
                        int a = manager.add(3, 2);
                        Log.d(TAG, "======Client add function reuslt : " + a);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
     
        @Override
        protected void onStart() {
            super.onStart();
            //绑定 remote service
            Intent intent = new Intent(this, CloudService.class);
            bindService(intent, connection, BIND_AUTO_CREATE);
        }
     
        @Override
        protected void onStop() {
            super.onStop();
            unbindService(connection);
        }
     
        //和remote service绑定时用的ServiceConnection对象
        private ServiceConnection connection = new ServiceConnection() {
     
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() 
                           + "] [ProcessId" + Process.myPid()
                           + "]  onServiceDisconnected");
            }
     
            @Override
            public void onServiceConnected(ComponentName name, IBinder service)
            {
                Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() 
                           + "] [ProcessId" + Process.myPid()
                           + "]  onServiceConnected");
                //将IBinder对象转为ICloudManager接口对象,实际上是创建了一个代理对象
                manager = ICloudManager.Stub.asInterface(service);
                findViewById(R.id.btn_print).setEnabled(true);
                findViewById(R.id.btn_add).setEnabled(true);
            }
        };
     
    }
  • 4) AndroidManifest.xml,声明程序组件Activity和Service
    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
    
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.cloud.test"
        android:versionCode="1"
        android:versionName="1.0" >
     
        <uses-sdk
            android:minSdkVersion="15"
            android:targetSdkVersion="15" />
     
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity android:name=".TestAc" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
            <!—remote service-->
            <service
                android:name=".CloudService"
                android:enabled="true"
                android:process=":remote" />
        </application>
     
    </manifest>

4.测试

  • 运行apk程序:

    app_test

id="uyan_ifr_2102619" scrolling="no" frameborder="0" src="http://api.v2.uyan.cc/v4/comment/?uid=1832578&frameid=2102619&du=&su=www.cloudchou.com%2F%3Fp%3D458&pic=http%3A%2F%2Fwww.cloudchou.com%2Fwp-content%2Fuploads%2F2014%2F04%2Fapp_f.png&url=http%3A%2F%2Fwww.cloudchou.com%2Fandroid%2Fpost-458.html&title=Binder%20service%E5%85%A5%E9%97%A8%E2%80%94%E5%BA%94%E7%94%A8%E5%B1%82binder%20service%20-%20Cloud%20Chou%27s%20Tech%20Blog&t=1477379125798" style="height: 1242px; width: 626px; display: block !important; border-width: 0px !important; border-style: none !important; overflow: hidden !important;">


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值