Service是android四大组件之一,和Activity不同的是Service是一个低调的“后台”工作者,脏活累活都是他干,但是用户却从来不会感到他的存在,因为Service没有UI,就是没有和用户交互的入口,这里需要提醒的是Service依然运行在主线程,如果没有在AndroidManifest没有配置process属性,默认情况下是和Activity一样都运行在主线程。
首先我们先介绍Service的两种用法,一种是startService()启动Service,另外一种是bindService()。
首先我们创建一个Service,当然Service创建完后需要在AndroidManifest中配置,不然不会启动。
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
Log.e("SERVICE", "onBind");
return new MyBinder();
}
class MyBinder extends IMyAidlInterface.Stub {
@Override
public void hello(String name) throws RemoteException {
Log.e("SERVICE", name);
}
}
@Override
public boolean onUnbind(Intent intent) {
Log.e("SERVICE", "onUnbind");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
super.onCreate();
Log.e("SERVICE", "onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("SERVICE", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.e("SERVICE", "onDestroy");
super.onDestroy();
}
}
我们先看看两种启动方式的生命周期。
1.startService的生命周如下
startService(new Intent(MainActivity.this, MyService.class));
启动
结束
2.bindService的生命周期如下
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
myAidlInterface.hello("Hello World");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
//在Activity onCreate()的时候进行bind
bindService(new Intent(MainActivity.this, MyService.class), connection, Context.BIND_AUTO_CREATE);
//在Activity onDestory()的时候进行bind
unbindService(connection);
如果我们再Activity的时候不调用unbindService(connection);就会报错。
05-26 17:12:18.305 18979-18979/com.sundroid.helloworld E/ActivityThread: Activity com.sundroid.helloworld.MainActivity has leaked ServiceConnection com.sundroid.helloworld.MainActivity$1@6a9294e that was originally bound here
android.app.ServiceConnectionLeaked: Activity com.sundroid.helloworld.MainActivity has leaked ServiceConnection com.sundroid.helloworld.MainActivity$1@6a9294e that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1092)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303)
at android.app.ContextImpl.bindService(ContextImpl.java:1286)
at android.content.ContextWrapper.bindService(ContextWrapper.java:604)
at com.sundroid.helloworld.MainActivity$2.onClick(MainActivity.java:57)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21350)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5574)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
启动
结束
在测试过程中,发现一个现象,就是如果我已经启动了一个Service,那么我再去bind或者是start的时候就不会走onCrteate(),这里的原因先不在本文进行介绍。Service的启动我们需要了解的先介绍这么多,如果有什么写的不妥的地方,欢迎读者留言,谢谢。