添加android service并通过getSystemService调用
2014-06-04 15:23
447 查看
大概实现类似TelephoneManager这样的远程服务,但是由于TelephoneManager是已经封装过的代理类,所以我们不需要去获取binder,但是对于调用另一个应用的service,需要通过aidl来通信。请注意:这两种实现方式会有区别,后面会附上代码。
这里主要讲前者,对于aidl实现跨进程调用大概介绍一下。
1).添加需要的Service的java文件。
注意:包名也要一样。package com.android.server;然后找到SystemServer,修改如下在ServerThread的run方法里添加:
注意"innertool"相当于service的标记,在使用getSystemService来获取时需要提供该标记。
2).frameworks\base\core\java\android\app\ContextImpl.java
这里主要是响应getSystemService,如果service未启动,则启动service。
3).aidl相关文件的编译
到这里基本就添加完成了,可能部分不同的平台或者项目会存在差异,大家需要细心。然后是对于远程service的调用
假设aidl定义的接口如下
即测试应用需要创建com.android.innertool这个包,并将IInnerToolService.aidl和IInnerToolCB.aidl文件放进去,这样会在gen/生成对应的java文件。
然后就可以使用该SystemService的接口了。
这样基本就走通了简单的调用流程。
附上相应的代码
代码如下:
这样调用的地方就可以通过bindService来获取该binder从而能跨进程通信
调用代码
通过两者对比,可以看到都是通过binder来通信的,不过由于获取binder的方式不同,所以代码有些区别。
另外注意,必须实现以下方法
但是这里必须要实现,因为在onTransact方法里会通过这个方法来获取参数
然后在接口里使用这个类时,需要添加限定符in,out,或者inout,否则编译不过。
例如在上面的aidl文件IInnerToolService里添加接口send(inout Entity entity),这里的in,out不明确的话,使用inout。
这里主要讲前者,对于aidl实现跨进程调用大概介绍一下。
1.添加service到SystemService
测试的service类是InnerToolService,表示内置到framework的自定义服务,使用的aidl包括:IInnerToolService 定义接口,InnerToolService实现该接口
IInnerToolCB.aidl 定义回调 不熟悉aidl的话可以先不加
1).添加需要的Service的java文件。
注意:包名也要一样。package com.android.server;然后找到SystemServer,修改如下在ServerThread的run方法里添加:
//add innertool try { ServiceManager.addService("innertool", new InnerToolService(context)); } catch (Throwable e) { } //End
注意"innertool"相当于service的标记,在使用getSystemService来获取时需要提供该标记。
2).frameworks\base\core\java\android\app\ContextImpl.java
这里主要是响应getSystemService,如果service未启动,则启动service。
首先添加import语句 //inner tool import com.android.innertool.IInnerToolService; //End
然后在内部类ServiceFetcher的static语句块里添加以下代码: //add innertool registerService("innertool", new ServiceFetcher() { public Object getService(ContextImpl ctx) { IBinder b = ServiceManager.getService("innertool"); IInnerToolService service = IInnerToolService.Stub.asInterface(b); Log.e("tool", "fetch innertool service = " + service); return service; }}); //End
3).aidl相关文件的编译
framework/base/Android.mk文件,在LOCAL_SRC_FILES下添加相关的aidl文件 LOCAL_SRC_FILES += \ innertool/java/com/android/innertool/IInnerToolService.aidl \ innertool/java/com/android/innertool/IInnerToolCB.aidl
到这里基本就添加完成了,可能部分不同的平台或者项目会存在差异,大家需要细心。然后是对于远程service的调用
假设aidl定义的接口如下
interface IInnerToolService{ void exec(String arg0,String arg1,IInnerToolCB arg2); }
2.通过aidl调用远程service
上面定义了aidl文件,使用的包名是com.android.innertool,那我们本地应用也需要有这个包名下的aidl文件即测试应用需要创建com.android.innertool这个包,并将IInnerToolService.aidl和IInnerToolCB.aidl文件放进去,这样会在gen/生成对应的java文件。
然后就可以使用该SystemService的接口了。
private IInnerToolService toolService2;
toolService2 = (IInnerToolService) getSystemService("innertool"); try { toolService2.exec("aaa", "bbb", new InnerToolCB()); } catch (RemoteException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }
这样基本就走通了简单的调用流程。
附上相应的代码
package com.android.server; import android.content.Context; import android.os.RemoteException; import android.util.Log; import com.android.innertool.IInnerToolCB; import com.android.innertool.IInnerToolService; public class InnerToolService extends IInnerToolService.Stub{ private Context mContext; public InnerToolService(Context context) { mContext = context; } @Override public void exec(String arg0, String arg1, IInnerToolCB arg2) throws RemoteException { // TODO Auto-generated method stub Log.v("InnerToolService", "exec,"+arg0+","+arg1+","+arg2); } }
3.下面简单的介绍调用其他应用的service
假设仍然以上面的接口作为测试,这样被调用的应用需要有一个Serivce来实现IInnerToolService.Stub并返回该binder代码如下:
package com.android.test; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class MyService extends Service{ private IInnerToolService.Stub binder = new IInnerToolService.Stub(){ @Override public void exec(String arg0, String arg1, IInnerToolCB arg2) throws RemoteException { // TODO Auto-generated method stub Log.v("InnerToolService", "exec,"+arg0+","+arg1+","+arg2); } }; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.v("InnerToolService", "onBind"); return binder; } }
这样调用的地方就可以通过bindService来获取该binder从而能跨进程通信
调用代码
private IInnerToolService toolService; private ServiceConnection mSerConn; mSerConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub toolService = IInnerToolService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } }; try { toolService.exec("aaa", "bbbb", new InnerToolCB()); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); }
通过两者对比,可以看到都是通过binder来通信的,不过由于获取binder的方式不同,所以代码有些区别。
4.aidl编译相关
如果是简单的接口文件,在mk文件里附上路径就可以,如果是Parcel类型,则需要实现java文件。因为aidl文件里只有一句声明package com.android.innertool; parcelable Entity;对于这个例子,则需要在com.android.innertool下创建Entity.java,并implements Parcelable,然后按需求设计相应的数据结构等。
另外注意,必须实现以下方法
public void writeToParcel(Parcel dest, int arg1) public void readFromParcel(Parcel _reply) // 这是系统解析aidl并生成java文件时在接口里要调用的对于第二个方法,大家也许会发现,平时使用intent传递的类型不需要重写啊,只需要实现Parcelable.Creator<AppAction> CREATOR
但是这里必须要实现,因为在onTransact方法里会通过这个方法来获取参数
_arg0 = com.android.innertool.Entity.CREATOR.createFromParcel(data);
然后在接口里使用这个类时,需要添加限定符in,out,或者inout,否则编译不过。
例如在上面的aidl文件IInnerToolService里添加接口send(inout Entity entity),这里的in,out不明确的话,使用inout。
相关文章推荐
- Android getSystemService()调用
- 为 Android 添加 Java 层服务也就是添加自定义的aidl服务到serviceManager 通过ServiceManager.getService取
- android中getSystemService通过系统提供的Manager接口来访问及设置服务数据
- Android之getSystemService()方法
- Android 关于getSystemService()方法的一些常用服务
- android getSystemService
- Android: 通过Runtime.getRuntime().exec调用底层Linux下的程序或脚本
- Android下通过root实现对system_server中binder的ioctl调用拦截
- 调试通过的android手机调用网上.net web service的例子
- Android之getSystemService 各种系统服务总结
- android中LayoutInflater的3种使用以及getSystemService的API
- Android: 通过Runtime.getRuntime().exec调用底层Linux下的程序或脚本
- Android之getSystemService方法实现详解
- Android之getSystemService
- Android下通过root实现对system_server中binder的ioctl调用拦截
- getSystemService方法的调用
- Android的 getSystemService
- getSystemService()是Android很重要的一个API
- Android下通过root实现对system_server中binder的ioctl调用拦截
- Androidの系统服务之getSystemService