android中怎么区分UI主线程和子线程

android中怎么区分UI主线程和子线程,第1张

在一个Android 程序开始运行的时候,会单独启动一个Process。默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broadcast Receiver)都会跑在这个Process。

一个Android 程序默认情况下也只有一个Process,但一个Process下却可以有许多个Thread。在这么多Thread当中,有一个Thread,我们称之为UI Thread。UI Thread在Android程序运行的时候就被创建,是一个Process当中的主线程Main Thread,主要是负责控制UI界面的显示、更新和控件交互。在Android程序创建之初,一个Process呈现的是单线程模型,所有的任务都在一个线程中运行。因此,我们认为,UI Thread所执行的每一个函数,所花费的时间都应该是越短越好。而其他比较费时的工作(访问网络,下载数据,查询数据库等),都应该交由子线程去执行,以免阻塞主线程。

那么,UI Thread如何和其他Thread一起工作呢?常用方法是:

诞生一个主线程的Handler物件,当做Listener去让子线程能将讯息Push到主线程的Message Quene里,以便触发主线程的handlerMessage()函数,让主线程知道子线程的状态,并在主线程更新UI。

方法有两种:

通过继承Thread类,重写Run方法来实现

通过继承接口Runnable实现多线程

主要接受子线程发送的数据, 并用此数据配合主线程更新UI

Handler的主要作用:主要用于异步消息的处理

Handler的运行过程:

当(子线程)发出一个消息之后,首先进入一个(主线程的)消息队列,发送消息的函数即刻返回,而在主线程中的Handler逐个的在消息队列中将消息取出,然后对消息进行处理。这样就实现了跨线程的UI更新(实际上还是在主线程中完成的)。

这种机制通常用来处理相对耗时比较长的 *** 作,如访问网络比较耗时的 *** 作,读取文大文件,比较耗时的 *** 作处理等。

在大白话一点的介绍它的运行过程:

启动应用时Android开启一个主线程

(也就是UI线程) , 如果此时需要一个耗时的 *** 作,例如:

联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些 *** 作放在主线程中,如果你放在主线程中的话,界面会出现假死现象(这也就是你在主线程中直接访问网络时会提示你异常的原因,如我们上篇文章所述Android主线程不能访问网络异常解决办法)。

new Handler(LoopergetMainLooper())由getMainLooper()可知是获取UI主线程looper,在UI线程中处理消息;

Handler handler = new Handler()会默认用当前线程的looper,一般情况是当前线程的异步线程与当前线程进行消息处理。

一般而言new Handler(LoopergetMainLooper())用于更新UI,Handler handler = new Handler()用于当前线程与异步线程的消息处理

稍微有过Andorid开发经验的同学都知道,Android开发中涉及到UI变动的 *** 作,必须在主线程中执行, 否则会crash

这就需要我们将代码抛到主线程执行。

第一种方式,是通过ActivityrunOnUiThread()来做。这不是一个好方法,毕竟Activity这种东西,在子线程中可遇不可求。也千万不要因此而将Activity传来传去,甚至对Context进行强转,那样太过难看。

那么,只剩下通过Handler手动将代码抛到主线程了。这就需要,Handler具有主线程的Looper对象。具体的原因可以参考我之前的博客:Android结合源码解析Android消息队列工作流程 。

两种实现方式:

1 在主线程中创建Handler

2 直接通过MainLooper,构造handler

>

其实谷歌早就意识到这个问题。Message里有一个send的方法。如下

Message msg = mhandlerobtainMessage(MSG_UPDATE, imgIndex, 0);

mhandlersendMessage(msg);

然后重写handler的 handlerMessage方法,如下:

private Handler mhandler = new Handler(){

@Override

public void handleMessage(Message msg){

if(msgwhat == MSG_UPDATE){

//你要的 *** 作

}

}

};

基本上就是这样啦!

以上就是关于android中怎么区分UI主线程和子线程全部的内容,包括:android中怎么区分UI主线程和子线程、快速切换到主线程更新UI的几种、Handler handler = new Handler()和new Handler(Looper.getMainLooper())的区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9553774.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存