最新消息:20210917 已从crifan.com换到crifan.org

【已解决】Android中context的startService对应的service运行机制

Android crifan 819浏览 0评论
折腾:
【未解决】Android项目rcsjta中如何才能运行到rcs的core的service
期间,先去确认前面的:
context.startService(new Intent(context, RcsCoreService.class));
context.startService后续启动service的机制 是不是 调用onCreate
Context  |  Android 开发者  |  Android Developers
https://developer.android.com/reference/android/content/Context
abstract ComponentName
startService(Intent service)
Request that a given application service be started.
android – Context.startService(intent) or startService(intent) – Stack Overflow
Start context.startService(intent) on Android Pie – Stack Overflow
Android中startService的使用及Service生命周期_孙群-CSDN博客_startservice生命周期
Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法
当我们通过调用了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的使用,不涉及任何bindService方法调用的情况。如果想了解bindService的相关使用,请参见《Android中bindService的使用及Service生命周期》。
https://blog.csdn.net/iispring/article/details/48169339
当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。
这样就清楚了机制了。
此处的是:
没有onStartCommand
但是有onBind
src/com/gsma/rcs/service/RcsCoreService.java
public IBinder onBind(Intent intent) {
    if (IContactService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("Contact service API binding");
        }
        return mContactApi;
    } else if (ICapabilityService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("Capability service API binding");
        }
        return mCapabilityApi;
    } else if (IFileTransferService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("File transfer service API binding");
        }
        return mFtApi;
    } else if (IChatService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("Chat service API binding");
        }
        return mChatApi;
    } else if (IVideoSharingService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("Video sharing service API binding");
        }
        return mVshApi;
    } else if (IImageSharingService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("Image sharing service API binding");
        }
        return mIshApi;
    } else if (IGeolocSharingService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("Geoloc sharing service API binding");
        }
        return mGshApi;
    } else if (IHistoryService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("History service API binding");
        }
        return mHistoryApi;
    } else if (IMultimediaSessionService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("Multimedia session API binding");
        }
        return mMmSessionApi;
    } else if (IFileUploadService.class.getName().equals(intent.getAction())) {
        if (sLogger.isActivated()) {
            sLogger.debug("File upload service API binding");
        }
        return mUploadApi;
    } else {
        return null;
    }
}
Android中bindService的使用及Service生命周期_孙群-CSDN博客_应用拉起bindservice会消耗什么资源
其中
public IBinder onBind(Intent intent) {
就有:IBinder
但是感觉此处RcsCoreService又不是bindService,而是startService
因为之前是被startService调用的
不过也不用深入研究了。
知道后续会先调用:
onCreate
再调用:
onStartCommand
(不过此处没有)
即可。

转载请注明:在路上 » 【已解决】Android中context的startService对应的service运行机制

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
93 queries in 0.192 seconds, using 23.38MB memory