第二篇:Android 学习之AIDL学习 :远程服务的绑定和通信

第二篇:Android学习之AIDL学习:

绑定远程服务

一、跨应用绑定服务Service:前言

在进行服务的绑定时,需要用到一个Service内自定以的Binder对象,而由于服务是远程的。所以,无法直接获取自定义Binder
类的定义。在Android中,有一种机制可以处理这种问题,就是通过使用AIDL来进行远程服务的绑定。
主要用道德就是后缀名时aidl的接口实现的。

二、实现

首先,需要有一个包含自定义服务的应用和一个普通应用。同时,需要在包含被调用服务的app中创建一个AIDL;创建方法如下:

  • 选中java文件夹右键创建AIDL文件。会在与java同级目录下创建一个相应的aidl文件夹,其中有一个package,包名和
    activity的一样。

    当创建好之后,需要在调用者目录下创建一个和被调用者相同的aidl文件夹,并在 其中创建相同的包,之后,将之前创建好
    的aidl复制进去即可。

这里以app1和app2为例。其中内部构造如下:
app1:MainActivity、MyService、IServiceRemoteAIDL
在app1中需要创建一个aidl接口供其他应用访问。定义如下:
- IServiceRemoteAIDL.aidl


 interface IServiceRemoteAIDL {
     /**
      * 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);
 }
  • MyService.java
public class MyService extends android.app.Service{
    public IBinder onBind(Intent intent){
        return new com.snowlive.service14.IServiceRemoteAIDL(){
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                                    double aDouble, String aString) throws RemoteException {

            }
        };
    }
    public void onCreate(){
        System.out.println("MyService is Start");
    }
}

这个例子主要是实现通过app2绑定app1的MyService
在进行远程服务的启动和绑定是都需要通过使用Intent的setComponent(ComponentName name)方法创建相应的Intent
对象。从而实现调用其他应用服务的功能。绑定和解绑远程服务方法和对普通服务的操作无异。

app2:MainActivity.java

public class MainActivity extends Activity implements ServiceConnection{
    private Intent serviceIntent; 
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            serviceIntent = new Intent();
            /**
            *这里的ComponentName(String packageName,String className);
             * 参数的含义依次为:服务的包名,服务的类名。 
            */
            serviceIntent.setComponent(new ComponentName("com.snowlive.service14","com.snowlive.service14.SendInfoService"));
           //绑定服务
           bindService(serviceIntent,this,(Context).BIND_AUTO_CREATE);
    }
    protected void onDestroy() {
        super.onDestroy();
        //解绑服务
        unbindService(this);
    }
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        System.out.println("Bind Service");
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
}

通过在Activity的onCreate方法设置serviceIntent,并调用
bindService(Intent intent,ServiceConnection conn,int tag)方法启动服务
在Activity的onDestroy方法调用stopService(ServiceConnectioin conn)方法停止服务。

三、远程服务数据通信

在实现此功能时,只需要在更改上面的IServiceRemoteAIDL、MyService、MainActivity即可。
这里以,更改MyService 中的一个内部数据为例。
注意:app1和app2的ISerivceRemoteAIDL是都需要更改的,更改的代码是一样的。

具体更改如下:

  • IServiceRemoteAIDL.aidl
interface IServiceRemoteAIDL {
     /**
      * 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);
     void setData(String data);//设置Service内部数值的方法
 }
  • MyService.java
public class MyService extends android.app.Service{
    private String data = "default data";
    public IBinder onBind(Intent intent){
        return new com.snowlive.service14.IServiceRemoteAIDL(){
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                                    double aDouble, String aString) throws RemoteException {

            }
             @Override
            public void setData(String data) throws RemoteException {
                SendInfoService.this.data = data;
            }

        };
    }
    public void onCreate(){
        new Thread(){
            public void run(){
                while(Running){
                    Log.w("MyServiceInfo:" ,data);
                    try{
                        Thread.sleep(1000);
                    }catch(Exception e){
                        e.printStackTrace();
                    }


                }
            }
        }.start();
        System.out.println("MyService is Start");
    }
    public void onDestroy(){
        super.onDestroy();
        Running = false;
    }

}

更改app2:MainActivity.java的同时需要在activity中添加一个id为bt_sync的按键,用于更改远程服务的数据
- app2 的MainActivity.java

public class MainActivity extends Activity implements ServiceConnection,View.OnClickListener{
    private Intent serviceIntent; 
    private com.snowlive.service14.IServiceRemoteAIDL remotebinder;//定义AIDL。
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            serviceIntent = new Intent();
            /**
            *这里的ComponentName(String packageName,String className);
             * 参数的含义依次为:服务的包名,服务的类名。 
            */
            serviceIntent.setComponent(new ComponentName("com.snowlive.service14","com.snowlive.service14.SendInfoService"));
           //绑定服务
           bindService(serviceIntent,this,(Context).BIND_AUTO_CREATE);
           findViewById(R.id.bt_sync).setOnClickListener(this);//为信息同步按键添加监听事件。

    }
    protected void onDestroy() {
        super.onDestroy();
        //解绑服务
        unbindService(this);
    }
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        System.out.println("Bind Service");
        //将接收到的Binder转化为IServiceRemoteAIDL
        remotebinder = IServiceRemoteAIDL.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
    public void onClick(View v){
           if(remotebinder!=null){
                try {
                    remotebinder.setData(etShow.getText().toString());
                    Toast.makeText(this,etShow.getText().toString(),Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

    }
}

综上,通过定义AIDL作为远程服务的Binder返回对象来实现绑定远程服务,和远程服务通信的功能。

四、总结:

再次回顾,绑定远程服务及和远程服务通行实现过程:
AIDL操作:
- 在需要被调用的远程服务应用中定义AIDL,将需要实现的方法定义在AIDL中。
- 将定义好的AIDL的结构,原封不动的复制到需要调用该服务的应用中(文件名->包名->AIDL)

被调用的服务Serivce
- 在onBinder()方法中将返回值设置为AIDL对象同时实现其中方法,对服务中的数据进行操作。
- 为Intent设置Component,在Component中设置远程服务的具体信息(报名,类全名)。

调用者Activity
- 定义调用远程服务的Intent,设置其Component属性。
- 定义AIDL对象,在服务链接时用于接收Binder对象。
- 实现SericeConnection接口,接收Binder对象。
- 添加事件响应机制,实现数据的传输和服务的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹振坤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值