1.Intent 启动service Activity方法集合
2. Acitivity 访问自己进程的service用startService就可以了,访问其中的方法,可以new Service().Method(不推荐)或者通过继承Binder方式来实现。
但是如果要访问系统service 或者 其他 进程(APK)的servcie的方法就要使用bindService +ASDL的方式。如果你只是简单的启动service而不使用service中的方法,则不需要使用ASDL。当然你也可以简单通过广播来实现通信。
还有一种比较新鲜的方法“Messenger ”!但是Messenger是线程安全的,如果要多线程访问servcie就要使用ASDL 了。
首先定义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); }
编写音乐servcie代码:
MyBinder内部类也可以这样定义
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文件。
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); //注意:这个bindService不能在onclick方法中调用。service中进行耗时操作也要起线程。 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); //myService = (IMediaPlaybackService)service;//Wrong !!!跨进程不可行 } @Override public void onServiceDisconnected(ComponentName name) { serviceConnection = null; } }; }