上一章介绍了直接调用Service来操作硬件的方法,如果我们再优化一下结构,通过一个Manager来调用这个Service的方法,可能会更好。这样Service就可以跑在后台,由于这时候service和manager是两个进程,所以只能通过IPC来进行通信。我们在上一篇看到
publicfinalclassLedServiceextendsILedService.Stub{}, ILedService.Stub就是
ILedService.aidl由aidl工具自动生成的类。
我们现在看看manager是如何实现的:
frameworks/base/core/java/mokoid/hardware/ILedService.aidl
- packagemokoid.hardware;
- interfaceILedService
- {
- booleansetOn(intled);
- booleansetOff(intled);
- }
该aidl文件最后能被aidl工具自动生成ILedService.java文件,提供了remotable的LedService可用的接口setOn和setOff.
frameworks/base/core/java/mokoid/hardware/LedManager.java
- publicclassLedManager
- {
- privatestaticfinalStringTAG="LedManager";
- privateILedServicemLedService;
- publicLedManager(){
- mLedService=ILedService.Stub.asInterface(
- ServiceManager.getService("led"));
- if(mLedService!=null){
- Log.i(TAG,"TheLedManagerobjectisready.");
- }
- }
- publicbooleanLedOn(intn){
- booleanresult=false;
- try{
- result=mLedService.setOn(n);
- }catch(RemoteExceptione){
- Log.e(TAG,"RemoteExceptioninLedManager.LedOn:",e);
- }
- returnresult;
- }
- publicbooleanLedOff(intn){
- booleanresult=false;
- try{
- result=mLedService.setOff(n);
- }catch(RemoteExceptione){
- Log.e(TAG,"RemoteExceptioninLedManager.LedOff:",e);
- }
- returnresult;
- }
- }
首先调用mLedService = ILedService.Stub.asInterface(ServiceManager.getService("led")); 得到远端的led service, 然后通过mLedService.setOn和mLedService.setOff来调用service的接口,从而操作硬件。
最后我们看看使用这种方法对应的应用程序代码:
apps/LedTest/src/com/mokoid/LedTest/LedSystemServer.java
- publicclassLedSystemServerextendsService{
- @Override
- publicIBinderonBind(Intentintent){
- returnnull;
- }
- publicvoidonStart(Intentintent,intstartId){
- Log.i("LedSystemServer","StartLedService...");
- /*PleasealsoseeSystemServer.javaforyourinterests.*/
- LedServicels=newLedService();
- try{
- ServiceManager.addService("led",ls);
- }catch(RuntimeExceptione){
- Log.e("LedSystemServer","StartLedServicefailed.");
- }
- }
- }
上面的代码实现了android的一个后台service,通过ServiceManager.addService把LedService加入到service中,这样就可以通过远程调用该service。
apps/LedTest/src/com/mokoid/LedTest/LedTest.java
- publicclassLedTestextendsActivityimplementsView.OnClickListener{
- privateLedManagermLedManager=null;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- //StartLedServiceinaseperatedprocess.
- startService(newIntent("com.mokoid.systemserver"));
- Buttonbtn=newButton(this);
- btn.setText("ClicktoturnLED1On");
- btn.setOnClickListener(this);
- setContentView(btn);
- }
- publicvoidonClick(Viewv){
- //GetLedManager.
- if(mLedManager==null){
- Log.i("LedTest","CreatanewLedManagerobject.");
- mLedManager=newLedManager();
- }
- if(mLedManager!=null){
- Log.i("LedTest","GotLedManagerobject.");
- }
- /**CallmethodsinLedServiceviaproxyobject
- *whichisprovidedbyLedManager.
- */
- mLedManager.LedOn(1);
- TextViewtv=newTextView(this);
- tv.setText("LED1isOn.");
- setContentView(tv);
- }
- }
上面代码首先启动了上面的service,然后当用户点击按钮时,会得到ledManager的实例,然后通过ledManager的接口LedOn点亮led。