开发的时候要用到aidl,基础是service 所以先来了解一下service:
Service一般会重写oncreate,onstart,ondestroy方法,oncreate方法会在service初次运行的时候调用,但是它只会调用一次:
StartService à oncreate à onstart;(第一次)
如果service已经启动了:
Startservice à onstart;
ondestroy方法会在结束service的时候被 调用,
stopService à ondestroy
service还用绑定的问题,service还有另外两个方法onbind onunbind方法
activity 一般绑定已经运行的服务,
bindService à onbind
unbindService à onunbind
在bind和unbind service的时候会用到一个接口 serviceconnection
这个接口定义了两个方法 onServiceConnected 和 onServiceDisconnected 这个两个方法分别会在绑定和解绑的时候被调用
注意上面的红字表示在activity中调用的方法
现在对service已经有基本的了解了,接下来就可以实现service三种实现方式中最简单两种了。
还有一个需要了解的概念就是service中最好有个binder内部对象这个对象继承自bind类,主要通过这个对象来获取service内部的信息以及方法。
接下来进入重点aidl:让其他应用程序复用该服务。这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。扩展名为aidl而不是java。这里的思想是:aidl就是类似一个接口,然后可以让service类和内部的bind类都实现这个接口,这样其他应用程序只需要通过这个接口就可以访问到service中的信息。
但是service中的binder是通过远程获得的,所以需要通过桩(Stub)来获取。桩对象是远程对象的本地代理。
下面是个aidl的例子这个例子拷贝自网上,觉得这个例子比我的要好,所以就用他的吧。
首先定义aidl文件:ICountSerivde.aidl
packagecom.easymorse;
interface ICountService {
int getCount();
}
在src目录的任何一个子目录下创建一个aidl文件都可以,创建出aidl文件后 eclipse会自动的在gen目录下创建对应的java类
接下来写服务类
package com.easymorse;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class CountService extends Service {
private boolean threadDisable;
private int count;
private ICountService.StubserviceBinder = new ICountService.Stub() {
@Override
public int getCount() throws RemoteException {
return count;
}
};
@Override
public IBinder onBind(Intent intent){
return serviceBinder;
}
@Override
public void onCreate() {
super .onCreate();
new Thread( new Runnable() {
@Override
public void run() {
while ( ! threadDisable) {
try {
Thread.sleep( 1000 );
} catch (InterruptedException e) {
}
count ++ ;
Log.v( " CountService " , " Count is " + count);
}
}
}).start();
}
@Override
public void onDestroy() {
super .onDestroy();
this .threadDisable = true ;
Log.v( " CountService " , " on destroy " );
}
}
AndroidManifest.xml文件:
<? xml version="1.0"encoding="utf-8" ?>
< manifest xmlns:android ="http://schemas.android.com/apk/res/android"
package ="com.easymorse" android:versionCode ="1" android:versionName ="1.0" >
< application android:icon ="@drawable/icon" android:label ="@string/app_name" >
< activity android:name =".LocalServiceDemoActivity"
android:label ="@string/app_name" >
< intent-filter >
< action android:name ="android.intent.action.MAIN" />
< category android:name ="android.intent.category.LAUNCHER" />
</ intent-filter >
</ activity >
< service android:name ="CountService" >
< intent-filter >
< action android:name ="com.easymorse.CountService" />
</ intent-filter >
</ service >
</ application >
< uses-sdk android:minSdkVersion ="3" />
</ manifest >
Activity:
package com.easymorse;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class LocalServiceDemoActivity extends Activity {
private ServiceConnectionserviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentNamename, IBinder service) {
countService = (ICountService) service;
try {
Log.v( " CountService " , " on serivce connected, count is "
+ countService.getCount());
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
@Override
public void onServiceDisconnected(ComponentNamename) {
countService = null ;
}
};
private ICountService countService;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.main);
this .bindService( new Intent( " com.easymorse.CountService " ),
this .serviceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
this .unbindService(serviceConnection);
super .onDestroy(); //注意先后
}
}
编写传递复杂数据类型的远程服务
远程服务往往不只是传递java基本数据类型。这时需要注意android的一些限制和规定:
android支持String和CharSequence
如果需要在aidl中使用其他aidl接口类型,需要import,即使是在相同包结构下;
android允许传递实现Parcelable接口的类,需要import;
android支持集合接口类型List和Map,但是有一些限制,元素必须是基本型或者上述三种情况,不需要import集合接口类,但是需要对元素涉及到的类型import;
非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。
最后贴上学习的网址:http://yangguangfu.iteye.com/blog/699306
最后在补充一点,如果service和药获取service 的activity不在同一个程序内,则通过activity 里面intent的setaction("这里是service的action")来得到这个service