Android 绑定远程服务(aidl文件的使用)

96
食梦兽
2015.10.25 17:03* 字数 575

关键字:隐式Intent开启服务 远程服务 aidl文件

前言上一篇文章 记录了Service两种启动方式的区别。这次继续说使用隐式Intent绑定远程服务,以及涉及到的aidl(安卓接口定义语言)文件。

前面两种开启服务的方式都使用的是显式的Intent,即new Intent(this, MyService.class)的形式。还可以通过隐式的Intent来开启服务。但必须知道该服务的action

开启本地服务在 上一篇文章 中有所记录。本篇和上篇中的不同仅在于实例化Intent时,

intent = new Intent();
intent.setAction("com.example.myservice");

和在Manifest.xml文件中配置Service要定义action

<service android:name=".MyService">
             <intent-filter>
                <action android:name="com.example.myservice"/>
            </intent-filter>        
</service>

这篇文章重点记录绑定远程服务。

绑定远程服务

远程服务是位于另一个项目中的一个对外开放的服务,区别于本地服务。

  • 远程服务:调用者和服务在不同的工程代码里面。
  • 本地服务:调用者和服务在同一个工程代码里面。

绑定远程服务的步骤:

  1. 在服务的内部创建一个内部类,提供一个方法,可以间接调用服务的方法
  2. 把暴露的接口文件的扩展名改为.aidl文件 去掉访问修饰符
  3. 实现服务的onbind方法,继承Bander和实现aidl定义的接口,提供给外界可调用的方法
  4. activity 中绑定服务。bindService()
  5. 在服务成功绑定的时候会回调 onServiceConnected方法 传递一个 IBinder对象
  6. aidl定义的接口.Stub.asInterface(binder) 调用接口里面的方法

.aidl:android interface definition language 安卓接口定义语言。
aidl文件都是公有的,没有访问权限修饰符。

我们要测试远程服务,就必须有两个不同的程序来进行交互。

提供远程服务的程序:
定义一个Service

public class MyService extends Service {

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        //返回MyBind对象
        return new MyBinder();
    }

    private void methodInMyService() {
        Toast.makeText(getApplicationContext(), "服务里的方法执行了。。。",
                Toast.LENGTH_SHORT).show();
    }

    /**
     * 直接继承IMyBinder.Stub
     */
     private class MyBinder extends IMyBinder.Stub {
        @Override
        public void invokeMethodInMyService() throws RemoteException {
            methodInMyService();
        }
    }
}

创建IMyBinder.aidl文件,工具会自动生成一个IMyBinder的接口。

interface IMyBinder {

     void invokeMethodInMyService();

}

Manifes.xml件中进行配置

 <service android:name=".MyService">
      <intent-filter>
            <action android:name="com.example.service" />
      </intent-filter>
</service>

调用远程服务的程序:

在此程序中,创建一个和远程服务程序的MyBinder.aidl一样的文件(包括包名)。

public class MainActivity extends Activity {

    private MyConn conn;
    private Intent intent;
    private IMyBinder myBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    //开启服务按钮的点击事件
    public void start(View view) {
        intent = new Intent(this, MyService.class);
        conn = new MyConn();
        //绑定服务,
        // 第一个参数是intent对象,表面开启的服务。
        // 第二个参数是绑定服务的监听器
        // 第三个参数一般为BIND_AUTO_CREATE常量,表示自动创建bind
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    //调用服务方法按钮的点击事件
    public void invoke(View view) {
        try {
            myBinder.invokeMethodInMyService();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private class MyConn implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //通过Stub得到接口类型
            myBinder = IMyBinder.Stub.asInterface(iBinder);
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    }
}
Android笔记
Web note ad 1