android 跨进程访问service方法(AIDL)

      Acitivity 访问自己进程的service用startService就可以了,访问其中的方法,可以new Service().Method(不推荐)或者通过继承Binder方式来实现。


但是如果要访问系统service (继承binder,ServiceManager.addService)或者 其他 进程(APK)的servcie(四大组件之一,实现onBind)的方法


就要使用bindService +ASDL的方式。如果你只是简单的启动service而


不使用service中的方法,则不需要使用 ASDL。当然你也可以简单通过广播来实现通信。

 还有一种比较新鲜的方法“Messenger”!但是Messenger是线程安全的,如果要多线程访问servcie就要使用ASDL 了。

 这里只介绍ASDL的方式,另外两种可以参考http://blog.csdn.net/lizhenmingdirk/article/details/7864737

 

 

 (1)首先定义Service端,比如一个播放音乐的MediaPlaybackService.

 

 定义一个ASDL 文件。注意Open方法得参数,in 的含义,AIDL 和普通的java 接口语法还是有差别的。

 如果希望 这个ASDL被编译为Java接口文件。需要在Android.mk文件中替换LOCAL_SRC_FILES如下编译选项。

 这样就会在out/target/common/obj/APPS/Music_intermediates/src/src/com/android/music生成  IMediaPlaybackService.java(负责通信,有兴趣可以看一下源码)接口文件 和IMediaPlaybackService.P文件,不需要将该接口文件拷贝到工程目录,就可通过import com.android.music.IMediaPlaybackService;引用它了。

 

 

Java代码 
  1. LOCAL_SRC_FILES := $(call all-java-files-under, src) \  
  2.         src/com/android/music/IMediaPlaybackService.aidl  
 

 

 

Java代码 
  1. package com.android.music;  
  2.   
  3. import android.graphics.Bitmap;  
  4.   
  5. interface IMediaPlaybackService  
  6. {  
  7.     void openFile(String path);  
  8.     void open(in long [] list, int position);  
  9.     int getQueuePosition();  
  10.     boolean isPlaying();  
  11.     void stop();  
  12.     void pause();  
  13.     void play();  
  14.     void prev();  
  15.     void next();  
  16.     long duration();  
  17.     long position();  
  18.     long seek(long pos);  
  19.     String getTrackName();  
  20.     String getAlbumName();  
  21.     long getAlbumId();  
  22.     String getArtistName();  
  23.     long getArtistId();  
  24.     void enqueue(in long [] list, int action);  
  25.     long [] getQueue();  
  26.     void moveQueueItem(int from, int to);  
  27.     void setQueuePosition(int index);  
  28.     String getPath();  
  29.     long getAudioId();  
  30.     void setShuffleMode(int shufflemode);  
  31.     int getShuffleMode();  
  32.     int removeTracks(int first, int last);  
  33.     int removeTrack(long id);  
  34.     void setRepeatMode(int repeatmode);  
  35.     int getRepeatMode();  
  36.     int getMediaMountedCount();  
  37.     int getAudioSessionId();  
  38.     void playAll(in long[] list, int position, boolean force);  
  39. }  
 

(2)编写音乐servcie代码,注意是继承了IMediaPlaybackService.Stub

   Java代码 

  1. public class MediaPlaybackService extends Service {  
  2.   
  3.         private IBinder binder = new MyBinder(this);  
  4.         @Override  
  5.         public IBinder onBind(Intent intent) {  
  6.             return binder;  
  7.         }  
  8.         public String play(){  
  9.             //......  
  10.         }  
  11.         public class MyBinder extends  IMediaPlaybackService.Stub{  
  12.   
  13.              WeakReference<MediaPlaybackService> mService;  
  14.   
  15.              MyBinder(MediaPlaybackService service) {  
  16.                     mService = new WeakReference<MediaPlaybackService>(service);  
  17.                 }  
  18.   
  19.             @Override  
  20.             public String play() {  
  21.                 return  mService.play();  
  22.             }  
  23.             @Override  
  24.             protected boolean onTransact(int code, Parcel data, Parcel reply,  
  25.                     int flags) throws RemoteException {  
  26.                 return super.onTransact(code, data, reply, flags);  
  27.             }  
  28.         }  
  29. }  
 

 

   修改Music Manifest.xml文件

 

Java代码 
  1. <service android:name="com.android.music.MediaPlaybackService"  
  2.             android:exported="true" >  
  3.           <intent-filter>    
  4.              <action         android:name="com.android.music.IMediaPlaybackService" />    
  5.            </intent-filter>    
  6.          </service>  

 

 至此 ,服务器端工作完毕。

 

 

 

 

 

客户端调用流程:

将Music的IMediaPlaybackService.asdl文件拷贝到 客户端工程,注意需要在客户端工程中建立和服务端相同的包结构。

这和webservice很像。 同样修改Android.mk文件使其生成IMediaPlaybackService.java文件。(其实完全可以copy服务器端的)

myService = IMediaPlaybackService.Stub.asInterface(service);  


aidl作为remote service是和local servie 一样 ,也是需要manifest声明,好让系统知道当前的service需要在系统注册

 

 

Java代码 
  1. import com.android.music.IMediaPlaybackService;  
Java代码 
  1. public class HelloActivity extends Activity {  
  2.       
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.   
  7.         View view = getLayoutInflater().inflate(R.layout.hello_activity, null);  
  8.         setContentView(view);  
  9.         //注意:这个bindService不能在onclick方法中调用。service中进行耗时操作也要起线程。  
  10.         boolean issuccess = bindService(new Intent("com.android.music.IMediaPlaybackService"),  
  11.                 serviceConnection, Context.BIND_AUTO_CREATE);  
  12.         Button btn = (Button)this.findViewById(R.id.text);  
  13.         btn.setOnClickListener(new View.OnClickListener(){  
  14.   
  15.             @Override  
  16.             public void onClick(View v) {  
  17.           
  18.                 try {  
  19.                     myService.pause();  
  20.                 } catch (RemoteException e) {  
  21.               
  22.                     e.printStackTrace();  
  23.                 }  
  24.             }  
  25.               
  26.         });  
  27.     }  
  28.     IMediaPlaybackService myService = null;  
  29.       
  30.     ServiceConnection serviceConnection = new ServiceConnection()  
  31.     {  
  32.   
  33.         @Override  
  34.         public void onServiceConnected(ComponentName name, IBinder service) {  
  35.               
  36.             myService = IMediaPlaybackService.Stub.asInterface(service);  
  37.             //myService = (IMediaPlaybackService)service;//Wrong !!!跨进程不可行  
  38.         }  
  39.         @Override  
  40.         public void onServiceDisconnected(ComponentName name) {  
  41.             serviceConnection = null;  
  42.         }  
  43.     };  
  44.   
  45. }  
 

你可能感兴趣的:(android 跨进程访问service方法(AIDL))