首页 > 试题广场 > 简述Andriod如何处理UI与耗时操作的通信,有哪些方式及各自的优缺点。
[问答题]
简述Andriod如何处理UI与耗时操作的通信,有哪些方式及各自的优缺点。

24个回答

添加回答
主要有三种方法,一为Handler,二为AsyncTask,三为自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui;
handler机制是,在主线程中创建handler对象,
当执行耗时操作时,新建一个线程,在这个线程中执行耗时操作,通过调用handler的sendMessage,post等方法,更新ui界面;

AsyncTask本质上是一个线程池,所有的异步任务都会在这个线程池中的工作线程中执行,当需要操作ui界面时,会和工作线程通过handler传递消息。

自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui,这种方法需要把context对象强制转换成activity后使用

handler机制的优点是  结构清晰,功能明确,但是代码过多;
asyncTask简单,快捷,但是可能会新开大量线程,消耗系统资源,造成FC
第三种方法最好用,代码也非常简单,只是需要传递context对象

编辑于 2015-08-22 13:25:46 回复(4)
1、启动worker线程进行耗时操作,通过Handler机制实现线程间通信。
2、AsyncTask处理
3、启用Service和broadcast广播
4、runOnUiThread()
5、post()


发表于 2015-04-02 11:33:24 回复(1)
 最常见的方式是通过handler的消息传递机制来完成的,其次还可以通过广播机制,以及第三方库EventBus去完成UI与耗时操作的通信。 
 1.Handler方式:这种方式是Android中最重要的消息传递机制,通过Handler,Looper,MessageQueue三者的协作完成消息的传递,
 实现简单原理:Handler发送通过sendmessage()发送消息,及把消息插入到messagequeue中,Looper不断的通过loop()方法轮询
 消息队列,如果里面有消息,就将消息取出并通过msg.targer.dispatchMessage() 去分发消息。然后Handler在UI线程中
 通过handlerMessage()去处理消息
 优点:使用范围广,可追踪方便调试,通信的载体是消息,而消息可以包括各
 种数据类型,还可以传递对象 
 缺点:原理较复杂 
 2.广播机制:通过系统广播或者自定义的广播去
 实现UI线程与耗时操作线程之间的通信 
 优点:实现简单 
 缺点:不利于调试,且消息传递不够灵活,会存在安全问题 
 3.EventBus:EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。
 比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现 
 优点:针对一个进程,解耦
 缺点:大量使用会不利于调式 
发表于 2015-09-05 11:02:18 回复(0)
(1)handler,工作线程执行耗时操作,然后handler发送消息和UI线程进行交互
(2)AsyncTask,注意里面的三个方法
(3)runOnUiThread(),强制执行在UI线程
(4) EventBus:事件发布和订阅总线,其只是一种规范,具体的实现主要有eventbus和otto
(5)RX响应式编程:这个是目前最新的,目前应用较广泛了,非常好用,代码非常优美,推荐大家使用。RX可做的可不只是这些!
编辑于 2016-07-14 22:08:28 回复(0)
- 首先分为 a.UI(主线程)与耗时操作(子线程)的通信处理方法? b.通信方式? C.每种方式的优缺点?
- (有时候,感觉这个题出的怪怪的,总是很难理解的样子,是因为太菜?)
- a.因为主线程如果进行耗时操作很容易发生ANR(程序无响应),而子线程又不能进行UI的绘制等,所以通常是把耗时操作放在子线程,在要进行UI改动的时候回到主线程,这样就涉及到了子线程与主线程的通信.常用的处理方法:Handler方式;AsyncTask;runOnUiThread();启用Service和broadcast广播;post();EventBus;不过runOnUiThread(),我们应该与Handler是一种原理,post,postDelayed,也是与Handler一种原理,AsyncTask貌似也是呢。
- b.方式就是上面的这些,那么我们为他们稍微介绍介绍一下:
- Handler,消息传递机制,线程通信方法,通过Handler,Looper,MessageQueue三者的协作完成消息的传递,每一个线程都会有自己对应的handler,looper,messagequeue,两个线程要通信,那么一线程调用二线程的Handler对象,发送消息。这个消息会被Handler发送到二线程的Messagequeue,同时被二线程的looper轮询到,然后处理,调用二线程的handlenMessage方法,来完成两个线程的通信
- AsyncTask,本质上是一个线程池,所有的异步任务都会在这个线程池中的工作线程中执行,当需要操作ui界面时,会和工作线程通过handler传递消息。
-  广播机制:通过系统广播或者自定义的广播去实现UI线程与耗时操作线程之间的通信 
-  EventBus:EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。
- c.优缺点
- Handler,优点:封装程度高,使用范围广,可追踪方便调试,通信的载体是消息,而消息可以包括各种数据类型,还可以传递对象 ,缺点:原理复杂?(在我看来线程通信,进程通信都复杂啊)
- AsyncTask,与Handler一样
- 广播机制,优点:四大组件的广播接收者以及Service,原理较易理解。缺点:不易调试,有所限制
- EventBus,优点:针对一个进程,解耦。缺点:大量使用会不利于调试
发表于 2016-08-07 19:05:42 回复(0)
答:Android中处理UI和耗时操作的通信,一个是AsyncTask.再一个就是Handler;
AsyncTask是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并在主线程中更新UI。从实现上来说,AsyncTask封装了Thread和Handler,通过AsyncTask可以更加方便地执行后台任务以及在主线程中访问UI,但是AsyncTask并不合适进行特别耗时的后台任务,对于特别耗时的任务来说,建议使用线程池。
它提供了四种核心方法:执行顺序为一下:
onPreExecute()----doInBackground()-----onProgressUpdate()----onPostExecute();
HandlerThread则是继承了Thread,它是一种可以使用Handler的Thread,它的实现也很简单,就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环,这样在实际的使用中就允许在HandlerThread中创建Handler了。
发表于 2016-04-19 07:58:07 回复(0)

1、handler

2、Activity.runOnUIThread(Runnable)

3、View.Post(Runnable)

4、View.PostDelayed(Runnabe,long)

5、AsyncTask

发表于 2015-08-17 21:05:16 回复(0)
UI处理主要是在主线程,耗时的操作我们一般都会放在另外一个线程来做,接下来面临的问题是如果耗时以后的操作需要通知ui,就会遇到通讯问题,android上目前提供了handler来解决这个问题,通过handler可以把需要的更新动作加入到主线程的处理队列中,Android也提供了AsyncTask来完成。他相当于封装了线程以及线程通知ui的操作。让你使用起来更方便。
handler的好处在于灵活松散,缺点在于代码不过紧凑
AsyncTask的好处在于业务逻辑和更新都可以非常好的放在一起。缺点个人觉得不够优雅,使用他的代码总是感觉很奇怪。

发表于 2015-04-23 13:54:16 回复(0)
wb头像 wb
主要有两种方法,一为Handler,二为AsyncTask;
handler机制是,在主线程中创建handler对象,
当执行耗时操作时,新建一个线程,在这个线程中执行耗时操作,通过调用handler的sendMessage,post等方法,更新ui界面;

AsyncTask本质上是一个线程池,所有的异步任务都会在这个线程池中的工作线程中执行,当需要操作ui界面时,会和工作线程通过handler
传递消息。

handler机制的优点是  结构清晰,功能明确,但是代码过多;
asyncTask简单,快捷,但是可能会新开大量线程,消耗系统资源,造成FC,
发表于 2015-04-21 18:06:42 回复(0)
1.AsyncTask(android封装好的异步api,但是注意内存泄露、取消任务执行不及时)
2. thread+handler(自己创建thread+handler进行线程切换)
3. threadPool+handler(四种线程池+handler)
4. 使用框架:RxJava/RxAndroid、EventBus
5. 使用IntentService
6. thread+广播
发表于 2017-08-24 20:26:59 回复(0)
个人认为有下面几个方案:
①直接用AsyncTask。优点嘛,就是方便,人家都给封装好了,肯定方便;缺点嘛,其一,每个Android版本的具体实现是不一样的,Android3.1之前是并行执行的,而之后又是串行执行相关任务,当然也可以调用先关方法使其做到并行执行;其二,他不能执行很耗时的任务;其三,每次必须重新new出一个实例执行新任务;
②使用handler。都知道,耗时操作肯定是放在子线程中的,无论是intentservice,还是刚刚说的asynctask,还是自己开启的子线程,我们都可以传给他一个和主线程关联的handler,耗时操作执行完毕的时候,利用handler发个消息来更新UI。当然,也可以不用传给他,直接调用handler=new Handler(Looper.getMainLooper())来创建主线程上的handler。
发表于 2017-06-13 09:59:39 回复(0)
1. Handler
Handler机制是,在主线程中创建Handler对象,当执行耗时操作时,新建一个线程,在这个线程中执行耗时操作,通过调用 Handler 的sendMessage,post等方法更新ui界面。
Handler机制的优点是结构清晰,功能明确;缺点是代码过多。
2. AsyncTask
AsyncTask本质上是一个线程池,所有的异步任务都会在这个线程池中的工作线程中执行,当需要操作ui界面时,会和工作线程通过handler传递消息。
Async Task优点是 简单,快捷;缺点是可能会新开大量线程,消耗系统资源,造成FC。
3. 为自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui
自己开子线程执行耗时操作,然后调用Activity的runOnUiThread()方法更新ui,这种方法需要把context对象强制转换成activity后使用
这种方法最好用,优点是代码非常简单,缺点是需要传递context对象。
发表于 2017-03-31 16:18:32 回复(0)
个人理解
1.handler
2.AsyncTask
3.Activity.runOnUiThread()
4.View.post()和View.postDelayed()

发表于 2016-07-21 15:09:59 回复(0)
1>通过线程和handler来进行,在新开的线程中执行耗时的操作,通过handler来进行UI的更新:
            优点:简单易于理解,便于编程实现
            缺点:无法提供大量的并发操作,程序的健壮性差,有大量的线程更新和销毁,内存消耗大
2>通过线程池,来进行后台任务的执行和UI的更新
            优点:可以避免大量线程的创建和销毁导致的内存消耗,而且可以个性化定制线城池
            缺点:要自行管理线程池,技术要求较高
3>通过异步任务来进行任务执行和UI更新
            优点:集成了线程池和UI的更新,可以大量并发,并且直接调用异步任务中的方法就可以更新ui
            缺点:无法准确的定制线程池的相关参数。
发表于 2016-04-02 16:52:47 回复(0)
Android中在UI中不能进行耗时操作,因为这样会产生ANR,那么耗时操作比如网络通信、数据库操作等都要放到子线程中去执行。关于子线程与主线程的通信有几种方法。方法一是通过Handler机制进行线程间通信,当子线程任务完成时,Handler便将消息发送到MessageQueue,Looper发现有新消息便将消息传递给Handler处理,Handler内部的handlerMessage便可以对消息进行处理,UI操作可以在这里执行。
方法二是使用AsyncTask,它是一个内部封装了Handler消息机制的类,在doInBackground中执行耗时操作,然后在onPostExecute中进行UI操作。
方法一的缺点是需要步骤比较复杂,而且每个耗时操作都要重新创建一个新线程,线程的创建跟销毁时很耗资源的,而且容易造成内存泄漏,因为可能在任务还没完成时Activity就退出了,而Handler持有对Activity的引用。那么方法二它内部实现线程池,自动管理线程的生命周期,而且它是对Handler机制的一种封装,节省了开发人员的工作。
发表于 2016-03-29 15:55:13 回复(0)
1. handler,looper,messagequeue,message结合
2. handler的post方法(传入runnable实例,松耦合)
3. View的post()方法(实际上也是调用handler的post方法,传入runnable实例)
4. Activity的runOnUiThread()方法
5. AsyncTask,Android包装的Handler机制方式来进行异步操作,通过以下方法来实现更新UI线程:
(1). onPreExecute()
这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。
(2). doInBackground(Params...)
这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。
(3). onProgressUpdate(Progress...)
当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应的更新。
(4). onPostExecute(Result)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如说提醒任务执行的结果,以及关闭掉进度条对话框等。
编辑于 2015-11-24 23:38:04 回复(0)
1.通过thread开启一个线程处理耗时的操作,处理完成之后通过handler实现线程间通信。
2.android封装的ayncTask来处理耗时的操作
3.通过开启intentService来处理耗时操作,intentService启动了一个工作线程处理任务,同时,使用一个队列管理请求地洞intentService的intent,当intentService处理完成时,在从队列中取出下一个intent处理任务。保证同一时间只有一个intent在调用intentService。
发表于 2015-10-05 10:35:14 回复(0)
<div> 1、通过Handler实现一步处理,与Thread进行配合使用<br /> 2、通过AsyncTask实现,开启一个异步线程,在该模块处理费时任务<br /> </div>
发表于 2015-09-05 14:19:38 回复(0)
<div> <ul> <li> Handler </li> </ul> 是Looper上处理Message的钩子工具。 </div> <div> 是UI层使用最广泛的通信方法。 </div> <div> View的post方法系列都在用。 </div> <div> 缺点是代码不容易解耦,进而有可能造成内存泄漏。 </div> <div> <ul> <li> 广播 </li> </ul> <div> 可以用LocalBroadcastManager在进程内通信。 </div> <div> 性能不如Handler好。 </div> <ul> <li> AIDL </li> </ul> </div> <div> 最适合跨进程通信,也是框架层各种服务间通信的标准实现。 </div> <div> 使用起来不如前两种方便。 </div> <div> <br /> </div>
发表于 2015-08-25 10:55:39 回复(0)
UI耗时操作放在新线程执行,不与MainThread一起。
发表于 2015-08-15 21:48:21 回复(0)
牛客网,程序员必备求职神器
QQ群:169195721
微 信:www_nowcoder_com 关注
微 博:牛客网 关注

扫一扫,把题目装进口袋