android四大组件之Service和子类IntentService

2024-02-09 13:18

本文主要是介绍android四大组件之Service和子类IntentService,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

四大组件中, Service跟Activity的生命周期非常类似,它也是可执行的.甚至可看做是没有界面的"Activity", 因为它的运行,用户并不会像Activity那样能看到它能呈现出来具体的视图界面. 同样,就像Activity一样, 需要继承Service来使用它的子类. 并且同样需要在AndroidManifest.xml中配置所定义的Service.


Service的生命周期


简述上面周期中的几个方法:

1, 如图示,Service 的几个方法onCreate(), onDestroy()是跟Activity一样的,都是创建和销毁前回调的方法.Service在Activity里被创建启动和停止, 也可以在自身使用stopSelf()来停止.


2, onStart() 在新版本已经被onStartCommand()所代替,如果是应用支持旧版本的系统,则继续用onStart().  onStart(0 和onStartCommand() 都是Service启动时会回调的方法. 如果是通过startService()来启动Service,那么每次启动都会回调onStartCommand() 这个方法.


3, onBind(), Service被绑定时回调的方法. 


4, onUnbind(), Service和所绑定的所有Activity都断开时会回调该方法.


这里要强调下Activity启动Service的两种方法和区别:

Activity可以通过startService() 和 bindService() 两个方法来启动. startService()启动Service, Activity和Service之间没有关联, 当Activity退出了,Service会继续存在并运行. 而bindService() 方式启动的话,Activity和Service是有关联的,Activity不仅能和Service通信,并且当Activity退出时,Service也会中止.下面会上个例子,通过代码看出区别:


配置方式

<Service android:name="com.test.service.MyBindService"><intent-filter><!-- 配置action就能像广播一样,通过action启动指定的Service --><action android:name="com.test.com.test.service.My_MSG"></intent-filter>
</Service>


新建两个Service:

*** 通过StartService()来启动的Service对象* @author Mr.Et**/
public class MyStartService extends Service{private String TAG = "MyStartService";@Overridepublic void onCreate(){Log.i(TAG, "onCreate()");super.onCreate();}/*** Service被启动后会回调该方法*/@Overridepublic int onStartCommand(Intent intent,int flags,int startId){Log.i(TAG, "onStartCommand()");super.onStartCommand(intent, flags, startId);return START_STICKY;}/*** (该方法必须被实现)* 绑定Service时会回调该方法*/@Overridepublic IBinder onBind(Intent intent) {//这里默认为空,如果需要传回Binder对象跟Activity通信//则可以继承Binder来实现返回对象即可.Log.i(TAG, "onBind()");return null;}@Overridepublic void onDestroy(){super.onDestroy();Log.i(TAG, "onDestroy()");}}

/*** 通过bindService()来启动的Service对象* @author Mr.Et**/
public class MyBindService extends Service{private String TAG = "MyBindService";public class MyBinder extends Binder{public void printContent(){Log.i(TAG, "print the content in Class - MyBinder.");}}/*** Service被创建是会回调该方法*/@Overridepublic void onCreate(){Log.i(TAG, "onCreate()");super.onCreate();}/*** Service被启动后会回调该方法*/@Overridepublic int onStartCommand(Intent intent,int flags,int startId){Log.i(TAG, "onStartCommand()");super.onStartCommand(intent, flags, startId);return START_STICKY;}/*** 绑定Service时会回调该方法*/@Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, "onBind()");// 返回Binder的子类MyBinder和Activity通信return new MyBinder();}/*** 如果前面是通过bindService()来绑定启动Service的,* 那么当解绑停止Service时会调用该方法*/@Overridepublic boolean onUnbind(Intent intent){Log.i(TAG, "onUnbind()");return true;}/*** Service被销毁前会回调该方法*/@Overridepublic void onDestroy(){Log.i(TAG, "onDestroy()");super.onDestroy();}}

启动Service的方法

第一种,startService()启动Service

Intent StartIntent = new Intent(this,MyStartService.class);/*** 通过startService()启动Service* 这种方式*/private void doStartService(){	//类似广播,也可以用setAction("XXX")使特定的Service启动//StartIntent.setAction("com.test.service.My_MSG");//创建Intent,跟跳转Activity的方式类似Intent StartIntent = new Intent(this,MyStartService.class);startService(StartIntent);}/*** 停止Service*/private void doStopService(){stopService(StartIntent);}

第二种,bindService()启动(绑定)Service

private MyBinder myBinder;private ServiceConnection conn = new ServiceConnection() {//当Activity和Service连接成功时会调用该方法@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stub//在这里通过自定义的Binder与Service通信myBinder = (MyBinder)service;}//当Activity和Service断开连接时会调用该方法@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}};/*** 通过bindService()启动(绑定)Service*/private void doBindSerive(){Intent bindIntent = new Intent();bindIntent.setAction("com.test.service.My_MSG");//当Service还没创建时,//第三个参数如果为0则不自动创建Service,为Service.BIND_AUTO_CREATE则自动创建bindService(bindIntent, conn, Service.BIND_AUTO_CREATE);}/*** 解除绑定Service*/private void doUnbindService(){unbindService(conn);}

ServiceConnection对象 conn是通过绑定方式启动,和Service通信的重要中介.当和Service连接成功和断开连接时都会回调里面的onServiceConnected() 和onServiceDisconnected() 方法. 但如果是用户主动使用unBindService()断开Activity和Service之间的连接,onServiceDisconnected()并不会被调用.因为系统将这视为正常情况. 只有是由于内存不足或其他原因导致异常中止Service和Activity之间的连接时,才会调用该方法. 并且可以通过在conn中获取Binder对象, 实现和Service的通信.

IntentService和Service的区别

系统提供了IntentService, 它是Service的子类.默认新建新的线程在运行. 而Service是缺少这个特质的,因为Service和调用者( 比如某个Activity )是运行在同一个进程中,会直接和调用竞争有限的资源,所以Service不适合用于处理耗时耗资源的任务,否则极易阻塞主线程导致ANR错误.

而IntentService 是这一情况的比较好的解决方案. 它自动实现多线程, 会新建工作线程专门处理任务, 同时使用了队列来管理请求启动IntentService的各个Intent. 比如当有3个intent都请求该IntentService,那么IntentService会按照队列顺序依次去新建线程,处理任务,保证在同一时间内只有一个intent在调用该intentService.当调用完毕会intentService会自动停止自身,并处理下一次的调用.直至最后.所以如果使用intentService, 用户并不需要主动的使用stopService() 或者在intentService中使用stopSelf()来停止.

继承IntentService必须实现onHandleIntent()方法, 将耗时的任务放在这个方法内即可. 其他方面,IntentService跟普通Service一样.




这篇关于android四大组件之Service和子类IntentService的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/694321

相关文章

四种Flutter子页面向父组件传递数据的方法介绍

《四种Flutter子页面向父组件传递数据的方法介绍》在Flutter中,如果父组件需要调用子组件的方法,可以通过常用的四种方式实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录方法 1:使用 GlobalKey 和 State 调用子组件方法方法 2:通过回调函数(Callb

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

基于Qt Qml实现时间轴组件

《基于QtQml实现时间轴组件》时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件,本文主要为大家详细介绍了如何使用Qml实现一个简单的时间轴组件,需要的可以参考下... 目录写在前面效果图组件概述实现细节1. 组件结构2. 属性定义3. 数据模型4. 事件项的添加和排序5. 事件项的渲染如何使用

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只