定义:四大组件之一
理解:service与activity都是运行在主线程中的,只不过activity对用户可见,service对用户不可见。虽运行在后台,但与线程概念无关。
使用:掌握生命周期,启动模式以及service与activity交互上各个生命周期的变化。
1,生命周期如下图所示,有两种类型,startService和bindService
接下来写个例子,例子参考上面的博客写的所以不全贴了,就一个service类,一个activity类,然后在menifest.xml中注册服务即可,两个类中都只打印了生命周期的log信息。
布局文件,就这一个页面四个按钮,启动服务,关闭服务,绑定服务,解绑服务 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context="service.ServiceActivity"> <Button android:id="@+id/start_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/start_service" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.382"/> <Button android:id="@+id/stop_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/stop_service" app:layout_constraintTop_toBottomOf="@+id/start_service" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <Button android:id="@+id/bind_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bind_service" app:layout_constraintTop_toBottomOf="@+id/stop_service" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> <Button android:id="@+id/unbind_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/unbind_service" app:layout_constraintTop_toBottomOf="@+id/bind_service" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
用于监听四个按钮的方法 private void initListener() { final Intent intent = new Intent(getApplicationContext(), MyService.class); mStartService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "start service"); startService(intent); } }); mStopService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "stop service"); stopService(intent); } }); mBindService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "bind service"); bindService(intent, mConnection, BIND_AUTO_CREATE); flag = true; } }); mUnBindService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "unbind service"); unbindService(mConnection); flag = false; } }); }
一:执行startService方式的生命周期
1.1,当在activity中点击启动服务即调用startService方法时,运行结果如下图所示,可以看到service生命周期执行onCreate -> onStartCommand
1.2,点击关闭服务如下图所示,可以看到只执行了onDestroy方法;当多次点击start service后只执行onStartCommand命令,只需一次stop service即可。
1.3,当启动服务,未关闭服务时直接按back键销毁activity,运行结果如下图所示,可以看到service并未销毁,它还会在后台运行,当你重新打开activity点击启动服务时,它只会执行onStartCommand方法,并不会执行onCreate方法,因为它还在。
二:执行bindService方式的生命周期
2.1,点击绑定服务按钮,观察生命周期如下图所示, 可以看到它的生命周期是onCreate -> onBind ,download是我在服务绑定后开启的一个模拟任务。
2.2,当点击解绑时,生命周期变为onUnbind -> onDestroy如下图所示
2.3,多次bind其实生命周期不会变化,而且一次unbind即可。
2.4,onServiceConnected方法中要判断binder是否为空,onServiceDisconnected要释放。
三:混合使用
如下图所示:
1,红色部分是先执行start service,然后bind service,之后点击了多次bind和start。最后先点击unbind service只是解绑,再点击stop service才是destroy。
2,绿色部分是先执行bind service,然后start service,之后点击多次bind和start。最后先stop然后unbind才destroy。
所以,可以看出当start和bind同时使用时,stop和unbind也必须同时使用才能destroy service。
补充:intentService就是继承自service,并且会开启工作线程去处理任务,处理完后会自动关闭服务。
参考:https://blog.youkuaiyun.com/lmj623565791/article/details/47143563