Android 远程Service

远程Service

在清单文件中给Service添加属性process 为:remote

<service  
        android:name="com.example.servicetest.MyService"  
        android:process=":remote" >  
    </service>  

使用远程Service,MyService将在另一个进程中运行,只会阻塞所在进程中的主线程,不会当前应用程序。

远程Service会在应用包名加上:remote;

 

远程Service的弊端:

开启多进程时 Application会运行两次 (初始化数据时不妥当 : 需要判断进程名与当前应用的的进程名)

使用bind方式与Activity建立连接时 程序会崩溃。

因为Service与Activity 运行在两个不同的进程中 ,不能使用传统的建立连接方式,需要引入AIDL;

 

Activity与远程Service 建立关联, 使用AIDL 进行跨进程通信(IPC)

AIDL(Android Interface Definition Languge) android接口定义语言 

AIDL的作用: 用于Service与多个应用程序组件之间进行跨进程通信 ,实现多个应用程序共享一个Service的功能

 

使用跨进程通信的步骤

1. 首先新建一个AIDL文件  进行文件MyAIDLService.aidl文件

package com.example.service.remote;

interface MyAIDLService
{
    int plus(int a, int b);  
    String toUpperCase(String str);  

}

//保存后,gen目录下会生产一个对应的java文件 ;

  //编写Aidl文件时,需要注意下面几点:


  1.接口名和aidl文件名相同。


  2.接口和方法前不用加访问权限修饰符public,private,protected等,也不能用final,static。


  3.Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、 CharSequence),使用这些类型时不需要import声明。对于List和Map中的元素类型必须是Aidl支持的类型。如果使用自定义类型作 为参数或返回值,自定义类型必须实现Parcelable接口。


  4.自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。


  5.在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数。


  6.Java原始类型默认的标记为in,不能为其它标记。

 

 

 

2、然后修改MyService中的代码   实现刚定义好的MyAIDLService接口  并且在onBInd中返回对象

   @Override  
    public IBinder onBind(Intent intent) {  
        return mBinder;  
    }  
  
    MyAIDLService.Stub mBinder = new Stub() {  
  
        @Override  
        public String toUpperCase(String str) throws RemoteException {  
            if (str != null) {  
                return str.toUpperCase();  
            }  
            return null;  
        }  
  
        @Override  
        public int plus(int a, int b) throws RemoteException {  
            return a + b;  
        }  
    };  

// Stub是Binderd的子类

 

3、在MainActivity中写实现代码

  private MyAIDLService myAIDLService;  
  
      //创建 ServiceConnection对象 并实现MyAIDLeService中的方法
private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) {
        // 获取MyAIDLService对象 myAIDLService
= MyAIDLService.Stub.asInterface(service); try { int result = myAIDLService.plus(3, 5); String upperStr = myAIDLService.toUpperCase("hello world"); Log.d("TAG", "result is " + result); Log.d("TAG", "upperStr is " + upperStr); } catch (RemoteException e) { e.printStackTrace(); } } };

 

4.在其他应用程序中调用MyService的方法  

4.1、在清单文件中给MyService 添加隐式Intent; 用于其他应用程序调用

<service android:name="com.example.service.remote.MyService"
                 android:process=":remote"
            >
            <intent-filter>
                <action android:name="com.example.service.remote.MyService.MyAIDLService"></action>
            </intent-filter>
            
        </service>
//MyService可以响应这个action的Intent

4.2.然后在一个新的项目中,把MyAIDLService.aidl文件拷贝过来(要将原有的包路径一起拷贝过来)

 

4.3 然后在MainActivity中  加入MyService建立关联的代码

  private MyAIDLService myAIDLService;  
  
      //创建 ServiceConnection对象    并实现MyAIDLeService中的方法
    private ServiceConnection connection = new ServiceConnection() {  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  
  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
        // 获取MyAIDLService对象
            myAIDLService = MyAIDLService.Stub.asInterface(service);  
            try {  
                int result = myAIDLService.plus(3, 5);  
                String upperStr = myAIDLService.toUpperCase("hello world");  
                Log.d("TAG", "result is " + result);  
                Log.d("TAG", "upperStr is " + upperStr);  
            } catch (RemoteException e) {  
                e.printStackTrace();  
            }  
        }  
    };  

4.4 bindService  通过隐式意图

case R.id.btn_bind:
            Intent intent1 = new Intent("com.example.service.remote.MyService.MyAIDLService");
            bindService(intent1, conn , BIND_AUTO_CREATE);
            break;

实现不同应用程序跨进程通信功能。

posted @ 2016-04-15 10:15  红尘Dream  阅读(366)  评论(0编辑  收藏  举报