service特性
1,Started Service,startService()//开启了服务,即会与服务失去联系,两者没有关联。即使访问者退出了,服务仍在运行。如需解除服务必须显式的调用stopService方法
2,Bound Service,bindService()//调用者与服务绑定在一起的。当调用者退出的时候,服务也随之退出。用于需要与服务交互。
3,默认情况,如果没有显示的指 service 所运行的进程, Service 和 activity 是运行在当前 app 所在进程的 main thread(UI 主线程)里面
4,service 里面不能执行耗时的操作(网络请求,拷贝数据库,大文件 )
Started Service
生命周期
onCreate(Client首次startService()) >> onStartCommand >> onDestroy(Client调用stopService())
当调用startService(Intent serviceIntent)后,如果Service是第一次启动:onCreate() >onStartCommand()
当再次调用startService(Intent serviceIntent),将只执行onStartCommand(),因为此时Service已经创建了,无需执行onCreate()回调
当调用stopService()即可将此Service终止,执行onDestroy()
public int onStartCommand(Intent intent, int flags, int startId)方法
flags默认情况下是0,对应的常量名为START_STICKY_COMPATIBILITY。
startId是一个唯一的整型,用于表示此次Client执行startService(…)的请求请求标识,在多次startService(…)的情况下,呈现0,1,2….递增。
此函数具有一个int型的返回值:
START_NOT_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,即使系统内存足够可用,系统也不会尝试重新创建此Service。除非程序中Client明确再次调用startService(…)启动此Service。
START_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,当系统内存足够可用的情况下,系统将会尝试重新创建此Service,一旦创建成功后将回调onStartCommand(…)方法,但其中的Intent将是null,pendingintent除外。
START_REDELIVER_INTENT:与START_STICKY唯一不同的是,回调onStartCommand(…)方法时,其中的Intent将是非空,将是最后一次调用startService(…)中的intent。
start方式启动服务
context.startService(Intent serviceIntent)启动Service
context.stopService(Intent serviceIntent)停止此Service
在Service内部,也可以通过stopSelf(…)方式停止其本身
public class MyService extends Service {
public static final String TAG = "MyService";
@Override
public IBinder onBind(Intent intent) {
//onBind(...)函数是Service基类中的唯一抽象方法,子类都必须重写实现。
//此函数的返回值是针对Bound Service类型的Service才有用的
//在Started Service类型中,此函数直接返回 null 即可
return null;
}
//onCreate()、onStartCommand()和onDestroy()都是Started Service相应生命周期阶段的回调函数。
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String name = intent.getStringExtra("name");
Log.w(TAG, "name:" + name);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
//启动service
Intent intent = new Intent(MainActivity.this, TestService.class);
startService(intent);
//停止service
stopService(intent);
//将service运行在不同的进程中
<service
android:name=".MyService"
android:exported="true"
android:process=":MyService" >
<intent-filter>
<action android:name="com.example.androidtest.myservice" />
</intent-filter>
</service>
Bound Service
生命周期
Service的生命周期是依附于Client的生命周期
当Client不存在时,Bound Service将执行onDestroy,同时通过Service中的Binder对象可以较为方便进行Client与Service之间的通信
onCreate() > onBind() > onUnbind() > onDestory()
Bound Service一般使用过程
1.自定义Service继承基类Service,并重写onBind(Intent intent)方法,此方法中需要返回具体的Binder对象;
2.Client通过实现ServiceConnection接口来自定义ServiceConnection,并通过bindService (Intent service, ServiceConnection sc, int flags)方法将Service绑定到此Client上;
3.自定义的ServiceConnection中实现onServiceConnected(ComponentName name, IBinder binder)方法,获取Service端Binder实例;
4.通过获取的Binder实例进行Service端其他公共方法的调用,以完成Client与Service之间的通信;
5.当Client在恰当的生命周期(如onDestroy等)时,此时需要解绑之前已经绑定的Service,通过调用函数unbindService(ServiceConnection sc)。
//bound service的使用方法
public class MyService extends Service {
public static final String TAG = "MyService";
private MyBinder mBinder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
class MyBinder extends Binder {
public void startDownload() {
// 执行具体的下载任务
}
}
}
//在使用到service的activity中实现
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//这里获取到service中的自定义binder对象
MyService.MyBinder myBinder = (MyService.MyBinder) service;
//调用binder中定义的方法
myBinder.startDownload();
}
};
//启动service
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
//停止service
unbindService(connection);