皮皮网

【产品上的溯源码】【android源码编译流程】【js polyfill方法源码】startservice源码

2024-11-19 09:40:21 来源:溯源码使用流程视频

1.startserviceԴ?源码产品上的溯源码?
2.startService 和 bindService的区别
3.Service的启动
4.android编程如何让程序后台运行
5.Android N 四大组件的工作原理

startservice源码

startserviceԴ??

       æœ€è¿‘在开发过程中遇到相关问题,在此记录过程及解决思路。

        1 原生已经实现功能

           Radio应用

           a 监听开机广播startService

           b 点应用图标后,bindService,实现与Service的通信

        2 需要新实现的功能

        其他应用接收开机广播后调用Radio应用,可能会startActivity,可能会startService, 被拉起后,恢复退出前的状态。

           a 恢复退出前的状态在Service中实现,在Service中的onBind和onStartCommand中可以获取Intent,

                从intent中获取标记位,如果需要恢复状态,恢复记录的band和channel。

            b 但是判断过程只需要一次,所以考虑是在onStartCommand中还是onBind中做该判断。

            c 测试发现,startService时,如果Service尚未启动,onBind和onStartCommand都会执行到,如果service已经启动,

               åˆ™åªæ‰§è¡ŒonStartCommand。

            d 所以将判断逻辑放在了onStartCommand中。

            e 另外一种情况,其他应用拉起来的是Activity,需要将intent中的标记位通知到service,之前是用的onBind,同样的原因,

               å½“service已经启动的情况下,onBind不会重新执行,并且,bind拉起来的service不会走到onStartCommand。

            f  而如果在Activity拉起来service的时候,只用startService的话,则只会走onStartCommand,无法实现Activity和Service的通信。

            g 所以最后实现,在activity中先startService再bindService。

        1  Service也是运行在主线程

            ä¸€ä¸ªæœåŠ¡ï¼ˆservice)运行在主线程中,服务并不创建自己的线程,也不在隔离进程中运行(除非你指定)。这意味着,如果你的服务要执行CPU费时操作或阻塞操作,你需要在服务中创建新的线程来执行该操作。使用其他线程,可以避免ANR错误,保证应用的主线程可以与用户交互。

            Service多用于不需要和用户进行交互的后台播放音乐,后台播放Radio等情况,如果涉及交互,只是不希望耗时,可以用thread。

        2 startService和bindService的区别

           a  交互

               é€šè¿‡startservice来启动一个service,启动后,service在后台运行。通常来说,该service是无法返回结果的。

               å¯ä»¥åˆ©ç”¨bindservice来和service绑定,绑定后,我们可以和service交互,发送请求,得到结果甚至执行IPC通信。

           b  生命周期

        startService

               é€šè¿‡è°ƒç”¨startService启动服务的过程:

               -》onCreate —》onStartCommand

               å¤šæ¬¡è°ƒç”¨startService,服务会多次执行:

               -》onStartCommand 

               å¤šæ¬¡è°ƒç”¨startService后,调用一次stopService即可结束服务。(若多次调用stopService,只有第一次有用)

               è°ƒç”¨stopService的服务结束过程

               -》onDestroy

        bindService

               è°ƒç”¨bindService启动服务的过程:

               -》onCreate —》onBind  —》(onServiceConnected)

               å¤šæ¬¡è°ƒç”¨bindService,服务本身未执行任何操作。

               ä¸€æ¬¡unBindService就能结束服务。(若多次调用unBindService,第一次有用,后面会出错)

               è°ƒç”¨unBindService的服务结束过程:

               -》onUnbind —》onDestroy

         å…ˆstartService后bindService

               å…ˆè°ƒç”¨startService,后调用bindService。服务的执行过程为:

               onCreate —》onStartCommand —》onStart —》onBind  —》(onServiceConnected)

               å…ˆunBindService,后stopService。服务结束的执行过程:

               onUnbind —》onDestroy

                需注意的是:unBindService会执行到onUnbind,stopService会执行到onDestroy。

               å…ˆstopService,后unBindService。服务结束的执行过程:

               onUnbind —》onDestroy

               éœ€æ³¨æ„çš„是:stopService不会执行任何操作,unBindService会执行到onUnbind—》onDestroy。

              先bindService后startService

               å…ˆè°ƒç”¨bindService,后调用startService。服务的执行过程为:

               onCreate —》onBind  —》(onServiceConnected) —》onStartCommand

               å…ˆunBindService,后stopService。

               æœåŠ¡æ‰§è¡Œçš„过程同 三。

               å…ˆstopService,后unBindService。服务结束的执行过程:

               æœåŠ¡æ‰§è¡Œçš„过程同 三

                总结:

               1、多次bindService时,服务本身的onBind不会被多次执行。

               2、bind上一个Service后,执行一次unBindService就够了。不然会出错。

               3、一个App里,同一个Activity多次bind一个服务,除了第一次,后面的bind不会有任何onBind、onServiceConnected打印。

                    一个App里,不同的Activity去bind一个服务,第一次bind有onBind、onServiceConnected打印,后面的bind只会             

                    onServiceConnected打印。

                4、一个Activity bind上一个Service后,如果Activity finish前没有调用unBind,App会崩溃,Log打印如下:

        android.app.ServiceConnectionLeaked: Activity com.example.testactivity1.MainActivity has leaked ServiceConnection

           com.example.testactivity1.MainActivity$1@d that was originally bound here.

         3  startForegroundService

              Android 8.0 有一项复杂功能;系统不允许后台应用创建后台服务。 因此,Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),以在前台启动新服务。

        在系统创建服务后,应用有五秒的时间来调用该服务的 startForeground() æ–¹æ³•ä»¥æ˜¾ç¤ºæ–°æœåŠ¡çš„用户可见通知。

        如果应用在此时间限制内未调用 startForeground(),则系统将停止服务并声明此应用为 ANR。

        8.0 以后不希望后台应用运行后台服务,除非特殊条件

        一旦通过startForegroundService() 启动前台服务,必须在service 中有startForeground() 配套,不然会出现ANR 或者crash

        startForeground() 中的id 和notification 不能为0 和 null

startService 和 bindService的区别

       1. 生命周期:

       startService()方式启动,Service是通过接受Intent并且会经历onCreate()和onStart()。当用户在发出

       æ„å›¾ä½¿ä¹‹é”€æ¯æ—¶ä¼šç»åŽ†onDestroy(),而bindService()方式启动,与Activity绑定的时候,会经历onCreate()和

       onBind(),而当Activity被销毁的时候,Service会先调用onUnbind()然后是onDestroy()。

       2. 控制方式:

       å‰è€…的控制方式需要使用固定的方法,对Service进行单一的操作。而后者由于与Activity绑定,不用考虑其生命周期问题,并且从发送

       Intent的被动操作,变为可以主动对Service对象进行操作,我们甚至可以建立一个Handler类,对Service进行相关的操作。大大加强

       äº†Service的灵活性、可操作性。

       æ€»ç»“:对于简单的应用startService()启动方式能带来更少的代码,简单的操作。对于复杂的应用bindService()方式,虽然带来的更多的编码,但同时也带来了更好的可操作性,使其使用起来更像Activity。