| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android多线程编程之Service -> 正文阅读 |
|
[移动开发]Android多线程编程之Service |
二、Android多线程编程1.线程的基本用法2.在子线程中更新UI3.解析异步消息处理机制?Android中异步消息处理主要由4个部分组成:Message、Handler、MessageQueue和Looper。 MessageMessage是在线程之间传递的消息,可以在内部携带少量的信息,用于在不同线程之间传递数据。 一般有wha字段、用来携带整形数据的args1、args2和携带Object对象的obj字段。 HandlerHandler是处理者的意思,主要用于发送和处理消息。发送消息一般是使用Handler的sendessage()方法、post()方法等,发出的消息最终会传递到Handler的handleMessage()方法中。 MessageQueueMessageQueue是消息队列的意思,主要用于存放所有通过Handler发送的消息。这部分消息会一直存在于消息队列中,的呢古代被处理。每个线程只有一个MessageQueue对象。 LooperLooper是每个线程中的MessageQueue的管家,调用Looper的loop()方法后,就会进入一个ie无限循环中,然后每当发现MessageQueue中存在一条消息时,就会将它取出,并传递到Handler的handleMessage()方法中。每个线程只会有一个Looper对象。 异步消息处理的整个流程:? ? ?? 首先需要在主线程中创建一个Handler对象,并重写handleMessage()方法。当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去。之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回Handler的handleMessage()方法中。如果Handler的构造函数中我们传入了Looper.getMainLooper(),handleMessaeg()方法中的代码就会在主线程中运行。如下所示: ? 三、Service的基本用法1.定义一个Servicenew->Service->Service,会弹出如下窗口: Exported属性表示是否将这个Service暴露给外部其他程序访问,Enabled属性表示是否启用这个Service 。 ????? 每个Service中最常用的3个方法: ????? onCreate()方法会在Service创建的时候调用,onStartCommand()方法会在每次Service启动的时候调用,onDestroy()方法会在Service销毁的时候调用。如下所示:
2.启动和停止Service?????? Context类中定义了startService()方法和stopService()方法,直接在Activity中调用这两个方法,就可以启动和停止Service 。如下所示,定义了两个按钮分别设置启动和停止:
注:onCreate()方法和onStartCommand()方法的区别: onCreate()方法是在Service第一次创建的时候调用的,而onStartCommand()方法则在每次启动Service的时候都会调用。为了验证这个说法,可以连续多点击几次startService的按钮,加入日志打印即可看出。 3.Activity和Service进行通信?????? 虽然Service是在Activity里启动的,但是在启动了Service之后,Acitivity与Service基本就没有什么关系了,调用Service的onCreate()方法和onStartCommand()方法后,Service就会一直处于运行状态,但具体运行的是什么逻辑,Activity就无法控制了。 ????? 比如说,如果希望在Service里提供一个下载功能,然后在Activity中决定何时开始下载,并可以岁时查看下载进度。实现这个功能的思路是创建一个专门的Binder对象来对下载功能进行管理,如下所示:
?然后在Activity中设置两个按钮分别用于绑定和取消绑定Service,当一个Activity和Service绑定了之后,就可以调用Service里的binder提供的方法了,如下所示:
?onServiceConnected()方法会在Activity与Service成功绑定的时候调用,而onServiceDsiconnected()方法只有在Service的创建进程崩溃或者被杀掉的时候才会调用。 通过调用onServiceConnected()方法,可以获取DownloadBinder实例,然后调用任何public方法。 bindService()方法将Acitivity和Service进行绑定,该方法接收3个参数,第一个参数是Intent对象,第二个对象是ServiceConnection实例,第三个参数是标志位,BIND_AUTO_CREATE表示在Activity和Service进行绑定后自动创建Service,调用onCreate()方法,但是onStartCommand()方法不会执行。 四、Service的生命周期1.启动Service?????? 一旦在项目的任何位置调用了Context的startService()方法,相应的Service就会自动启动,并回调onStartCommand()方法。如果这个Service之前还没有创建国,onCreate()方法会先于onStartCommand()方法执行。Service启动了之后会一直保持运行状态,直到stopService()或stopSelf()方法被调用,或者被系统回收。 ??????? 注:理论上来说,每调用一次startService()方法,onStartCommand()就会执行一次,但实际上每个Service只会存在一个实例。所以不管你调用了多少次startService()方法,只需调用一次stopService()或stopSelf()方法,Service就会停止。 2.建立连接?????? 另外,还可以调用Context的bindService()来获取一个Service的持久连接,这时就会回调Service中的onBind()方法。同样,如果这个Service还没有创建过,onCreae()方法会先于onBind()方法执行。之后,可以获取到onBind()方法里返回的IBinder对象的实例,这样就可以和Service进行通信了。只要连接没有断开,Service就会一直保持运行状态,直到被系统回收。 3.销毁?????? 当调用了startService()方法后,再去调用stopService()方法。这时Service中的onDestroy()方法就会执行,表示Service已经销毁了。同样的,当调用了bindService()方法后,再去调用unbindService()方法,onDestroy()方法也会执行。 ?????? 注:如果对一个Service既调用了startService()方法,又调用了bindService()方法,根据Android系统的机制,一个Service只要被启动或者被绑定了之后,就会处于运行状态,必须要让以上两种条件都不满足,Service才能被销毁。所以,这种情况必须同时调用stopService()和unbindService()方法,onDestroy()方法才会执行。 五、Service的更多技巧1.使用前台Service?????? 从Android8.0系统开始,只有当应用保持在前台可见状态的情况下,Service才能保证稳定运行,一旦应用进入后台之后,Service随时都有可能被系统回收。如果希望Service能够一直保持运行状态,可以考虑使用前台Service。前台Service和普通Service最大的区别在于,一直会有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,类似于通知的效果。 ?????? 由于状态栏中一直有一个正在运行的图标,相当于我们的应用以另外一种形式保持在前台可见状态,所以系统不会倾向于回收前台Service。另外,用户也可以通过下拉状态栏清楚地指导当前什么应用正在与兴宁,因此也不存在某些恶意应用长期在后台偷偷占用收集资源的情况。 ?????? 使用前台Servcie,关键是调用了startForeground()方法,让Service变成一个前台Service,并在系统状态栏显示出来。这个方法接受两个参数:第一个参数是通知的id,类似notify方法的第一个参数;第二个参数是构建的Notification对象。如下所示:
??????? 从Android9.0系统开始,使用前台Servcie必须在AndroidManifest.xml文件中进行权限声明。如下所示:
?????? 以前台Service的模式启动服务后,在系统状态栏会显示一个通知图表,即使退出应用程序,Service也会一直处于运行状态,而且不用担心会被系统回收。Service对应的通知也会一直显示在状态栏上面。如果不希望程序一直运行,也可以选择手动杀掉应用,这样Service就会跟着一起停止运行了。 2.使用IntentService?????? Service中的代码都是默认运行主线程当中的,如果直接在Service里处理一些耗时的逻辑,就很容易出现ANR的情况。 ?????? 所以一般情况下,应该在Service的每个具体的方法里开启一个子线程,然后在这里处理那些耗时的逻辑。但是这种Service一旦启动,就会一直处于运行状态,必须调用stopService()或stopSelf()反法,或者被系统回收,Service才会停止。实现一个Service在执行完毕后自动停止的功能,如下所示:
上面这种写法并不复杂,但是有些时候总会忘记开启线程,或者忘记调用stopSelf()方法。为了可以简单地创建一个异步的、会自动停止的Service,Andriod专门提供了一个IntentService类,这个类就很好地解决了这些问题。如下所示:
为了验证这一说法,可以在UI设计一个按钮,用于启动IntentService,并打印线程id,如下所示:
在xml布局文件中设置:
注意别忘了在AndroidManifest.xml中声明,一般来说,使用AndroidStudio来创建一个Servcie,声明都会自动创建:
最终的验证这里就不展示了,可以想象,IntentService的线程name和主线程的肯定不一样,并且,IntentService的onDestroy()方法也会触发。 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 19:53:43- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |