远程Servicejava
在清单文件中给Service添加属性process 为:remoteandroid
<service android:name="com.example.servicetest.MyService" android:process=":remote" > </service>
使用远程Service,MyService将在另外一个进程中运行,只会阻塞所在进程中的主线程,不会当前应用程序。ide
远程Service会在应用包名加上:remote;spa
远程Service的弊端:线程
开启多进程时 Application会运行两次 (初始化数据时不稳当 : 须要判断进程名与当前应用的的进程名)
code
使用bind方式与Activity创建链接时 程序会崩溃。
对象
由于Service与Activity 运行在两个不一样的进程中 ,不能使用传统的创建链接方式,须要引入AIDL;blog
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,不能为其它标记。
二、而后修改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的子类
三、在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.一、在清单文件中给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;
实现不一样应用程序跨进程通讯功能。