请选择 进入手机版 | 继续访问电脑版

[Android] Android startService的利用 与Service生命周期案例详解

  [复制链接]
查看677 | 回复212 | 2021-9-14 04:38:44 | 显示全部楼层 |阅读模式

Android中有两种重要 方式利用 Service,通过调用Context的startService方法或调用Context的bindService方法,本文只探究 纯startService的利用 ,不涉及任何bindService方法调用的环境 。假如 想相识 bindService的相干 利用 ,请参见《Android中bindService的利用 及Service生命周期》。

当我们通过调用了Context的startService方法后,我们便启动了Service,通过startService方法启动的Service会不停 无穷 期地运行下去,只有在外部调用Context的stopService或Service内部调用Service的stopSelf方法时,该Service才会制止 运行并烧毁 。

要想利用 Service,起首 我们要继承自Service,然后重写如下方法:
onCreate, onStartCommand, onBind 和 onDestroy。

这几个方法都是回调方法,都是由Android操作体系 在合适的机遇 调用的,并且必要 留意 的是这几个回调方法都是在主线程中被调用的。

onCreate: 实验 startService方法时,假如 Service没有运行的时间 会创建该Service并实验 Service的onCreate回调方法;假如 Service已经处于运行中,那么实验 startService方法不会实验 Service的onCreate方法。也就是说假如 多次实验 了Context的startService方法启动Service,Service方法的onCreate方法只会在第一次创建Service的时间 调用一次,以后均不会再次调用。我们可以在onCreate方法中完成一些Service初始化相干 的操作。

onStartCommand: 在实验 了startService方法之后,有大概 会调用Service的onCreate方法,在这之后肯定 会实验 Service的onStartCommand回调方法。也就是说,假如 多次实验 了Context的startService方法,那么Service的onStartCommand方法也会相应的多次调用。onStartCommand方法很告急 ,我们在该方法中根据传入的Intent参数举行 现实 的操作,比如会在此处创建一个线程用于下载数据或播放音乐等。

onBind: Service中的onBind方法是抽象方法,以是 Service类本身就是抽象类,也就是onBind方法是必须重写的,即使我们用不到。在通过startService利用 Service时,我们在重写onBind方法时,只必要 将其返回null即可。onBind方法重要 是用于给bindService方法调用Service时才会利用 到。

onDestroy: 通过startService方法启动的Service会无穷 期运行,只有当调用了Context的stopService或在Service内部调用stopSelf方法时,Service才会制止 运行并烧毁 ,在烧毁 的时间 会实验 Service回调函数。

我们为了探究通过startService方法启动的Service的生命周期以验证上面对 各个回调函数方法的形貌 ,写了如下的一个测试案例。
起首 创建一个服务类TestService,该类继承自Service,代码如下:

  1. package com.ispring.startservicedemo;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.util.Log;
  6. public class TestService extends Service {
  7. @Override
  8. public void onCreate() {
  9. Log.i("DemoLog","TestService -> onCreate, Thread ID: " + Thread.currentThread().getId());
  10. super.onCreate();
  11. }
  12. @Override
  13. public int onStartCommand(Intent intent, int flags, int startId) {
  14. Log.i("DemoLog", "TestService -> onStartCommand, startId: " + startId + ", Thread ID: " + Thread.currentThread().getId());
  15. return START_STICKY;
  16. }
  17. @Override
  18. public IBinder onBind(Intent intent) {
  19. Log.i("DemoLog", "TestService -> onBind, Thread ID: " + Thread.currentThread().getId());
  20. return null;
  21. }
  22. @Override
  23. public void onDestroy() {
  24. Log.i("DemoLog", "TestService -> onDestroy, Thread ID: " + Thread.currentThread().getId());
  25. super.onDestroy();
  26. }
  27. }
复制代码

我们在TestService的各个回调方法中只是简单打印出了相应的信息,并没有做很多复杂的处理操作。

然后我们在Activity中调用该Serivce,Activity中相应的代码如下:

  1. package com.ispring.startservicedemo;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.util.Log;
  6. public class MainActivity extends Activity {
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. Log.i("DemoLog", "Thread ID: " + Thread.currentThread().getId());
  12. Log.i("DemoLog", "before test startService");
  13. //连续启动Service
  14. Intent intent1 = new Intent(this, TestService.class);
  15. startService(intent1);
  16. Intent intent2 = new Intent(this, TestService.class);
  17. startService(intent2);
  18. Intent intent3 = new Intent(this, TestService.class);
  19. startService(intent3);
  20. //停止Service
  21. Intent intent4 = new Intent(this, TestService.class);
  22. stopService(intent4);
  23. //再次启动Service
  24. Intent intent5 = new Intent(this, TestService.class);
  25. startService(intent5);
  26. Log.i("DemoLog", "after test startService");
  27. }
  28. }
复制代码

我们在Activity中,起首 连续 三次调用了Activity的startService方法以启动Service,然后调用Activity的stopService方法制止 Service,然后又通过调用Activity的startService方法启动Service。

运行程序的输出效果 如下:

我们分析一下上面的输出效果 ,起首 打印出了主线程的ID是1, 然后我们发现后面全部 在回调函数中打印出的实验 线程的ID也就是1,这就阐明 了Service中的各个回调方法是运行在主线程中的。其次我们可以发如今 我们连续 调用了三次startService方法之后,只触发了一次onCreate回调方法,触发了三次onStartCommand方法,在onStartCommand中我们可以读取到通过startService方法传入的Intent对象,并且这三次的startId都不同,分别是1,2,3,每次调用startService都会自动 分配一个startId,startId可以用来区分不同的startService的调用,一样平常 环境 下startId都是从1开始计数,以后每次调用startService之后startId自动 加一递增。

之后我们又调用了Activity的stopService(intent4)方法用于制止 Service,通过输出效果 我们发现Service实验 了onDestroy方法,一样平常 环境 下我们可以在onDestroy方法中实验 一些资源开释 的操作。实验 完onDestroy之后该Service的实例就烧毁 了。固然 我们之前调用了三次startService方法,但是只要调用一次stopService就可以让运行中的Service制止 运行并烧毁 。

末了 我们再次通过startService(intent5)启动Service时,通过输出效果 我们发现再次实验 了Service的onCreate方法,这阐明 Service在通过stopService烧毁 之后重新创建了,并随之再次调用onStartCommand回调方法,并且startId再次从1开始计数。

末了 必要 留意 的是我们在Activity中操作Service的开始和末了 处分别写了两句输出代码,分别是

  1. Log.i("DemoLog", "before test startService");
复制代码

  1. Log.i("DemoLog", "after test startService");
复制代码

但是我们再看一下输出效果 会发现,程序直接上来在输出了before test startService之后,却立即 输出了after test startService,在这之后才是TestService内部各个回调方法的输出,这阐明 startService()方法和stopService()方法在实验 完后立即 返回了,也就是这两个方法都不是壅闭 式的,启动service和制止 service都是异步操作,startService()、stopService()都是将intent对象发送给Android Framework,然后Framework层异步地启动、制止 Service。

我们用一张图来概括一下通过startService启动的Service的生命周期:

这里写图片形貌

当Android面对 内存匮乏的时间 ,大概 会烧毁 掉你当前运行的Service,然后待内存充足的时间 可以重新创建Service,Service被Android体系 逼迫 烧毁 并再次重修 的举动 依赖 于Service中onStartCommand方法的返回值。我们常用的返回值有三种值,START_NOT_STICKY、START_STICKY和START_REDELIVER_INTENT,这三个值都是Service中的静态常量。

START_NOT_STICKY: 假如 返回START_NOT_STICKY,表示当Service运行的历程 被Android体系 逼迫 杀掉之后,不会重新创建该Service,当然假如 在其被杀掉之后一段时间又调用了startService,那么该Service又将被实例化。那什么情境下返回该值比较适当 呢?假如 我们某个Service实验 的工作被制止 几次无关告急 或者对Android内存告急 的环境 下必要 被杀掉且不会立即 重新创建这种举动 也可担当 ,那么我们便可将 onStartCommand的返回值设置为START_NOT_STICKY。举个例子,某个Service必要 定时从服务器获取最新数据:通过一个定时器每隔指定的N分钟让定时器启动Service去获取服务端的最新数据。当实验 到Service的onStartCommand时,在该方法内再规划一个N分钟后的定时器用于再次启动该Service并开发 一个新的线程去实验 网络操作。假设Service在从服务器获取最新数据的过程中被Android体系 逼迫 杀掉,Service不会再重新创建,这也不要紧 ,由于 再过N分钟定时器就会再次启动该Service并重新获取数据。

START_STICKY: 假如 返回START_STICKY,表示Service运行的历程 被Android体系 逼迫 杀掉之后,Android体系 会将该Service依然设置为started状态(即运行状态),但是不再保存onStartCommand方法传入的intent对象,然后Android体系 会尝试再次重新创建该Service,并实验 onStartCommand回调方法,但是onStartCommand回调方法的Intent参数为null,也就是onStartCommand方法固然 会实验 但是获取不到intent信息。假如 你的Service可以在恣意 时候 运行或竣事 都没什么题目 ,而且不必要 intent信息,那么就可以在onStartCommand方法中返回START_STICKY,比如一个用来播放背景音乐功能的Service就得当 返回该值。

START_REDELIVER_INTENT: 假如 返回START_REDELIVER_INTENT,表示Service运行的历程 被Android体系 逼迫 杀掉之后,与返回START_STICKY的环境 雷同 ,Android体系 会将再次重新创建该Service,并实验 onStartCommand回调方法,但是不同的是,Android体系 会再次将Service在被杀掉之前末了 一次传入onStartCommand方法中的Intent再次保留下来并再次传入到重新创建后的Service的onStartCommand方法中,如许 我们就能读取到intent参数。只要返回START_REDELIVER_INTENT,那么onStartCommand重的intent肯定 不是null。假如 我们的Service必要 依赖 具体 的Intent才能运行(必要 从Intent中读取相干 数据信息等),并且在逼迫 烧毁 后有必要重新创建运行,那么如许 的Service就得当 返回START_REDELIVER_INTENT。

到此这篇关于Android startService的利用 与Service生命周期案例详解的文章就先容 到这了,更多相干 Android startService的利用 与Service生命周期内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的相干 文章盼望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar penguinzhuyun | 2021-9-14 14:22:27 | 显示全部楼层
听admin楼主一席话,省我十本书!
回复

使用道具 举报

avatar 遨瀚 | 2021-9-17 07:34:35 | 显示全部楼层
admin楼主加油,看好你哦!
回复

使用道具 举报

avatar 今夕何夕535 | 2021-9-17 20:31:58 | 显示全部楼层
我只看看不说话。。。
回复

使用道具 举报

avatar 123457748 | 2021-9-20 02:46:48 | 显示全部楼层
admin楼主,我告诉你一个你不知道的的秘密,有一个牛逼的源码论坛他的站点都是商业源码,还是免费下载的那种!特别好用。访问地址:http://www.mxswl.com 猫先森网络
回复

使用道具 举报

avatar 天下第一菜鸟俅 | 2021-9-20 02:52:54 | 显示全部楼层
不是惊喜,是惊吓!
回复

使用道具 举报

avatar udeyozozoha | 2021-9-20 02:52:55 | 显示全部楼层
Patient wxq.sgxx.jbkt.net.ycv.ge hypertonia, lowest price for generic viagra cheap lowest price discount generic prednisone prednisone prednisone prices propecia stromectol from india stromectol lowest prednisone prices 3 generic stromectol in australia generic eli online bactrim ventolin stromectol generic stromectol lowest price fildena professional for sale overnight prednisone canada deprivation <a href="http://oliveogrill.com/walmart-viagra-100mg-price/">100 mg viagra lowest price</a> <a href="http://naturalgolfsolutions.com/prednisone-without-pres/">canadian pharmacy prednisone 10 mg</a> <a href="http://ossoccer.org/drugs/prednisone/">buy 5mg prednisone without prescription</a> <a href="http://naturalbloodpressuresolutions.com/propecia/">propecia</a> <a href="http://coastal-ims.com/generic-stromectol/">generic stromectol</a> <a href="http://stephacking.com/drugs/stromectol/">low cost stromectol</a> <a href="http://stephacking.com/cheap-prednisone-online/">where to buy prednisone online</a> <a href="http://stephacking.com/drugs/buying-stromectol-online/">buy stromectol without prescription</a> <a href="http://coachchuckmartin.com/drugs/eli/">eli 20mg online</a> eli 20 mg ndc <a href="http://bayridersgroup.com/bactrim/">buy trimethoprim</a> <a href="http://center4family.com/ventolin/">ventolin</a> <a href="http://eyogsupplements.com/item/cheap-stromectol-online/">cheap stromectol online</a> <a href="http://greatlakestributarymodeling.net/pill/fildena-professional/">online fildena professional no prescription</a> <a href="http://aawaaart.com/prednisone-canada/">prednisone</a> chorioretinitis http://oliveogrill.com/walmart-viagra-100mg-price/ cheapviagra.com http://naturalgolfsolutions.com/prednisone-without-pres/ lowest price prednisone http://ossoccer.org/drugs/prednisone/ prednisone http://naturalbloodpressuresolutions.com/propecia/ propecia http://coastal-ims.com/generic-stromectol/ safe web site for stromectol http://stephacking.com/drugs/stromectol/ stromectol http://stephacking.com/cheap-prednisone-online/ prednisone http://stephacking.com/drugs/buying-stromectol-online/ buy generic stromectol http://coachchuckmartin.com/drugs/eli/ cheap eli online http://bayridersgroup.com/bactrim/ pediatric bactrim http://center4family.com/ventolin/ ventolin http://eyogsupplements.com/item/cheap-stromectol-online/ stromectol generic canada http://greatlakestributarymodeling.net/pill/fildena-professional/ cheap fildena professional online http://aawaaart.com/prednisone-canada/ prednisone canada nasolacrimal amikacin confirmation.
回复

使用道具 举报

avatar 南黑天家 | 2021-9-20 02:52:57 | 显示全部楼层
admin楼主,你妈妈喊你回家吃饭!
回复

使用道具 举报

avatar 豪哥692 | 2021-9-20 02:53:00 | 显示全部楼层
这么版块的帖子越来越有深度了!
回复

使用道具 举报

avatar 楚一帆 | 2021-9-20 02:53:08 | 显示全部楼层
雷锋做好事不留名,都写在帖子里!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则