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;引用它了。
- LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- src/com/android/music/IMediaPlaybackService.aidl
- package com.android.music;
-
- import android.graphics.Bitmap;
-
- interface IMediaPlaybackService
- {
- void openFile(String path);
- void open(in long [] list, int position);
- int getQueuePosition();
- boolean isPlaying();
- void stop();
- void pause();
- void play();
- void prev();
- void next();
- long duration();
- long position();
- long seek(long pos);
- String getTrackName();
- String getAlbumName();
- long getAlbumId();
- String getArtistName();
- long getArtistId();
- void enqueue(in long [] list, int action);
- long [] getQueue();
- void moveQueueItem(int from, int to);
- void setQueuePosition(int index);
- String getPath();
- long getAudioId();
- void setShuffleMode(int shufflemode);
- int getShuffleMode();
- int removeTracks(int first, int last);
- int removeTrack(long id);
- void setRepeatMode(int repeatmode);
- int getRepeatMode();
- int getMediaMountedCount();
- int getAudioSessionId();
- void playAll(in long[] list, int position, boolean force);
- }
(2)编写音乐servcie代码,注意是继承了IMediaPlaybackService.Stub:
Java代码
- public class MediaPlaybackService extends Service {
-
- private IBinder binder = new MyBinder(this);
- @Override
- public IBinder onBind(Intent intent) {
- return binder;
- }
- public String play(){
-
- }
- public class MyBinder extends IMediaPlaybackService.Stub{
-
- WeakReference<MediaPlaybackService> mService;
-
- MyBinder(MediaPlaybackService service) {
- mService = new WeakReference<MediaPlaybackService>(service);
- }
-
- @Override
- public String play() {
- return mService.play();
- }
- @Override
- protected boolean onTransact(int code, Parcel data, Parcel reply,
- int flags) throws RemoteException {
- return super.onTransact(code, data, reply, flags);
- }
- }
- }
修改Music Manifest.xml文件
- <service android:name="com.android.music.MediaPlaybackService"
- android:exported="true" >
- <intent-filter>
- <action android:name="com.android.music.IMediaPlaybackService" />
- </intent-filter>
- </service>
至此 ,服务器端工作完毕。
客户端调用流程:
将Music的IMediaPlaybackService.asdl文件拷贝到 客户端工程,注意需要在客户端工程中建立和服务端相同的包结构。
这和webservice很像。 同样修改Android.mk文件使其生成IMediaPlaybackService.java文件。(其实完全可以copy服务器端的)
myService = IMediaPlaybackService.Stub.asInterface(service);
aidl作为remote service是和local servie 一样 ,也是需要manifest声明,好让系统知道当前的service需要在系统注册
- import com.android.music.IMediaPlaybackService;
- public class HelloActivity extends Activity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- View view = getLayoutInflater().inflate(R.layout.hello_activity, null);
- setContentView(view);
-
- boolean issuccess = bindService(new Intent("com.android.music.IMediaPlaybackService"),
- serviceConnection, Context.BIND_AUTO_CREATE);
- Button btn = (Button)this.findViewById(R.id.text);
- btn.setOnClickListener(new View.OnClickListener(){
-
- @Override
- public void onClick(View v) {
-
- try {
- myService.pause();
- } catch (RemoteException e) {
-
- e.printStackTrace();
- }
- }
-
- });
- }
- IMediaPlaybackService myService = null;
-
- ServiceConnection serviceConnection = new ServiceConnection()
- {
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
-
- myService = IMediaPlaybackService.Stub.asInterface(service);
-
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- serviceConnection = null;
- }
- };
-
- }