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

来源:互联网 发布:从零开始学法语软件 编辑:程序博客网 时间:2024/06/14 23:36

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

绑定远程服务

  • 第二篇Android学习之AIDL学习
    • 绑定远程服务
      • 一跨应用绑定服务Service前言
      • 二实现
      • 三远程服务数据通信
      • 四总结

一、跨应用绑定服务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对象。
- 添加事件响应机制,实现数据的传输和服务的操作。

0 0
原创粉丝点击