在android 线程安全队列中,使用线程来做一些操作是不是非常不安全?

Android中UI线程与后台线程交互设计的5种方法_西西软件资讯
西西软件下载最安全的下载网站、值得信赖的软件下载站!
→ Android中UI线程与后台线程交互设计的5种方法
1.0.6 官方最新版
类型:图像浏览大小:13.0M语言:英文 评分:4.2
我想关于这个话题已经有很多前辈讨论过了。今天算是一次学习总结吧。在android的设计思想中,为了确保用户顺滑的操作体验。一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务。因此我们必须要重新开启一个后台线程运行这些任务。然而,往往这些任务最终又会直接或者间接的需要访问和控制UI控件。例如访问网络获取数据,然后需要将这些数据处理显示出来。就出现了上面所说的情况。原本这是在正常不过的现象了,但是android规定除了UI线程外,其他线程都不可以对那些UI控件访问和操控。为了解决这个问题,于是就引出了我们今天的话题。Android中后台线程如何与UI线程交互。据我所知android提供了以下几种方法,用于实现后台线程与UI线程的交互。1、handler2、Activity.runOnUIThread(Runnable)3、View.Post(Runnable)4、View.PostDelayed(Runnabe,long)5、AsyncTask方法一:handlerhandler是android中专门用来在线程之间传递信息类的工具。要讲明handler的用法非常简单,但是我在这里会少许深入的讲一下handler的运行机制。为了能够让handler在线程间传递消息,我们还需要用到几个类。他们是looper,messageQueue,message。这里说的looper可不是前段时间的好莱坞大片环形使者,他的主要功能是为特定单一线程运行一个消息环。一个线程对应一个looper。同样一个looper对应一个线程。这就是所谓的特定单一。一般情况下,在一个线程创建时他本身是不会生产他特定单一的looper的(主线程是个特例)。因此我们需要手动的把一个looper与线程相关联。其方法只需在需要关联的looper的线程中调用Looper.prepare。之后我们再调用Looper.loop启动looper。说了这么多looper的事情,到底这个looper有什么用哪。其实之前我们已经说到了,他是为线程运行一个消息环。具体的说,在我们将特定单一looper与线程关联的时候,looper会同时生产一个messageQueue。他是一个消息队列,looper会不停的从messageQuee中取出消息,也就是message。然后线程就会根据message中的内容进行相应的操作。那么messageQueue中的message是从哪里来的哪?那就要提到handler了。在我们创建handler的时候,我们需要与特定的looper绑定。这样通过handler我们就可以把message传递给特定的looper,继而传递给特定的线程。在这里,looper和handler并非一一对应的。一个looper可以对应多个handler,而一个handler只能对应一个looper(突然想起了一夫多妻制,呵呵)。这里补充一下,handler和looper的绑定,是在构建handler的时候实现的,具体查询handler的构造函数。在我们创建handler并与相应looper绑定之后,我们就可以传递message了。我们只需要调用handler的sendMessage函数,将message作为参数传递给相应线程。之后这个message就会被塞进looper的messageQueue。然后再被looper取出来交给线程处理。这里要补充说一下message,虽然我们可以自己创建一个新的message,但是更加推荐的是调用handler的obtainMessage方法来获取一个message。这个方法的作用是从系统的消息池中取出一个message,这样就可以避免message创建和销毁带来的资源浪费了(这也就是算得上重复利用的绿色之举了吧)。突然发现有一点很重要的地方没有讲到,那就是线程从looper收到message之后他是如何做出响应的嘞。其实原来线程所需要做出何种响应需要我们在我们自定义的handler类中的handleMessage重构方法中编写。之后才是之前说的创建handler并绑定looper。好吧说的可能哟点乱,总结一下利用handler传递信息的方法。假设A线程要传递信息给B线程,我们需要做的就是1、在B线程中调用Looper.prepare和Looper.loop。(主线程不需要)2、 编写Handler类,重写其中的handleMessage方法。3、创建Handler类的实例,并绑定looper4、调用handler的sentMessage方法发送消息。到这里,我们想handler的运行机制我应该是阐述的差不多了吧,最后再附上一段代码,供大家参考。&1&public&class&MyHandlerActivity&extends&Activity&{
&2&&&&&&TextView&textV
&3&&&&&&MyHandler&myH
&5&&&&&&protected&void&onCreate(Bundle&savedInstanceState)&{
&6&&&&&&&&&&super.onCreate(savedInstanceState);
&7&&&&&&&&&&setContentView(R.layout.handler);
&9&&&&&&&&&&//实现创建handler并与looper绑定。这里没有涉及looper与
&&&&&&&&&&&&//线程的关联是因为主线程在创建之初就已有looper
10&&&&&&&&&&myHandler=MyHandler(MyHandlerActivitythis.getMainLooper());
11&&&&&&&&&&textView&=&(textView)&findViewById(R.id.textView);
12&&&&&&&&&
13&&&&&&&&&&MyThread&m&=&new&MyThread();
14&&&&&&&&&&new&Thread(m).start();
18&&&&&&class&MyHandler&extends&Handler&{
19&&&&&&&&&&public&MyHandler()&{
20&&&&&&&&&&}
22&&&&&&&&&&public&MyHandler(Looper&L)&{
23&&&&&&&&&&&&&&super(L);
24&&&&&&&&&&}
26&&&&&&&&&&//&必须重写这个方法,用于处理message
27&&&&&&&&&&@Override
28&&&&&&&&&&public&void&handleMessage(Message&msg)&{
29&&&&&&&&&&&&&&//&这里用于更新UI
30&&&&&&&&&&&&&&Bundle&b&=&msg.getData();
31&&&&&&&&&&&&&&String&color&=&b.getString(&color&);
32&&&&&&&&&&&&&&MyHandlerActivity.this.textView.setText(color);
33&&&&&&&&&&}
36&&&&&&class&MyThread&implements&Runnable&{
37&&&&&&&&&&public&void&run()&{
38&&&&&&&&&&&&&&//从消息池中取出一个message
39&&&&&&&&&&&&&&Message&msg&=&myHandler.obtainMessage();
40&&&&&&&&&&&&&&//Bundle是message中的数据
41&&&&&&&&&&&&&&Bundle&b&=&new&Bundle();
42&&&&&&&&&&&&&&b.putString(&color&,&&我的&);
43&&&&&&&&&&&&&&msg.setData(b);
44&&&&&&&&&&&&&&//传递数据
45&&&&&&&&&&&&&&myHandler.sendMessage(msg);&//&向Handler发送消息,更新UI
46&&&&&&&&&&}
47&&&&&&}方法二:Activity.runOnUIThread(Runnable)&这个方法相当简单,我们要做的只是以下几步1、编写后台线程,这回你可以直接调用UI控件2、创建后台线程的实例3、调用UI线程对应的Activity的runOnUIThread方法,将后台线程实例作为参数传入其中。注意:无需调用后台线程的start方法方法三:View.Post(Runnable)&该方法和方法二基本相同,只是在后台线程中能操控的UI控件被限制了,只能是指定的UI控件View。方法如下1、编写后台线程,这回你可以直接调用UI控件,但是该UI控件只能是View2、创建后台线程的实例3、调用UI控件View的post方法,将后台线程实例作为参数传入其中。方法四:View.PostDelayed(Runnabe,long)该方法是方法三的补充,long参数用于制定多少时间后运行后台进程&方法五:AsyncTaskAsyncTask是一个专门用来处理后台进程与UI线程的工具。通过AsyncTask,我们可以非常方便的进行后台线程和UI线程之间的交流。那么AsyncTask是如何工作的哪。AsyncTask拥有3个重要参数1、Params&2、Progress3、ResultParams是后台线程所需的参数。在后台线程进行作业的时候,他需要外界为其提供必要的参数,就好像是一个用于下载图片的后台进程,他需要的参数就是图片的下载地址。Progress是后台线程处理作业的进度。依旧上面的例子说,就是下载图片这个任务完成了多少,是20%还是60%。这个数字是由Progress提供。Result是后台线程运行的结果,也就是需要提交给UI线程的信息。按照上面的例子来说,就是下载完成的图片。AsyncTask还拥有4个重要的回调方法。1、onPreExecute2、doInBackground3、onProgressUpdate4、onPostExecuteonPreExecute运行在UI线程,主要目的是为后台线程的运行做准备。当他运行完成后,他会调用doInBackground方法。doInBackground运行在后台线程,他用来负责运行任务。他拥有参数Params,并且返回Result。在后台线程的运行当中,为了能够更新作业完成的进度,需要在doInbackground方法中调用PublishProgress方法。该方法拥有参数Progress。通过该方法可以更新Progress的数据。然后当调用完PublishProgress方法,他会调用onProgressUpdate方法用于更新进度。onProgressUpdate运行在UI线程,主要目的是用来更新UI线程中显示进度的UI控件。他拥有Progress参数。在doInBackground中调用PublishProgress之后,就会自动调onProgressUpdate方法onPostExecute运行在UI线程,当doInBackground方法运行完后,他会调用onPostExecute方法,并传入Result。在onPostExecute方法中,就可以将Result更新到UI控件上。明白了上面的3个参数和4个方法,你要做的就是1、编写一个继承AsyncTask的类,并声明3个参数的类型,编写4个回调方法的内容。2、然后在UI线程中创建该类(必须在UI线程中创建)。3、最后调用AsyncTask的execute方法,传入Parmas参数(同样必须在UI线程中调用)。这样就大功告成了。另外值得注意的2点就是,千万不要直接调用那四个回调方法。还有就是一个AsyncTask实例只能执行一次,否则就出错哦。以上是AsyncTask的基本用法,更加详细的内容请参考android官方文档。最后附上一段代码,供大家参考。&1&private&class&DownloadFilesTask&extends&AsyncTask&URL,&Integer,&Long&&
&2&//在这里声明了Params、Progress、Result参数的类型
&4&&&&&//因为这里不需要使用onPreExecute回调方法,所以就没有加入该方法
&6&&&&&//后台线程的目的是更具URL下载数据
&7&&&&&&protected&Long&doInBackground(URL...&urls)&{
&8&&&&&&&&&&int&count&=&urls.//urls是数组,不止一个下载链接
&9&&&&&&&&&&long&totalSize&=&0;//下载的数据
10&&&&&&&&&&for&(int&i&=&0;&i&&&&i++)&{
11&&&&&&&&&&&&&&//Download是用于下载的一个类,和AsyncTask无关,大家可以忽略他的实现
12&&&&&&&&&&&&&&totalSize&+=&Downloader.downloadFile(urls[i]);
13&&&&&&&&&&&&&&publishProgress((int)&((i&/&(float)&count)&*&100));//更新下载的进度
14&&&&&&&&&&&&&&//&Escape&early&if&cancel()&is&called
15&&&&&&&&&&&&&&if&(isCancelled())&
16&&&&&&&&&&}
17&&&&&&&&&&return&totalS
20&&&&&&//更新下载进度
21&&&&&&protected&void&onProgressUpdate(Integer...&progress)&{
22&&&&&&&&&&setProgressPercent(progress[0]);
25&&&&&&//将下载的数据更新到UI线程
26&&&&&&protected&void&onPostExecute(Long&result)&{
27&&&&&&&&&&showDialog(&Downloaded&&&+&result&+&&&bytes&);
30&有了上面的这个类,接下你要做的就是在UI线程中创建实例,并调用execute方法,传入URl参数就可以了。这上面的5种方法各有优点。但是究其根本,其实后面四种方法都是基于handler方法的包装。在一般的情形下后面四种似乎更值得推荐。但是当情形比较复杂,还是推荐使用handler。最后补充一下,这是我的第一篇博客。存在很多问题请大家多多指教。尤其是文中涉及到内容,有严重的技术问题,大家一定要给我指明啊。拜托各位了。
04-2504-2504-2504-2104-1504-1504-1304-1304-1204-08
阅读本文后您有什么感想? 已有23人给出评价!
名称大小下载当前位置: →
→ Android中后台线程与UI线程的交互
Android中后台线程与UI线程的交互
& 作者及来源: BananaMonster - 博客园 &
&收藏到→_→:
摘要: Android中后台线程与UI线程的交互
"Android中后台线程与UI线程的交互"::
我想关于这个话题已经有很多前辈讨论过了。今天算是一次学习总结吧。
在android的设计思想中,为了确保用户顺滑的操作体验。一些耗时的任务不能够在ui线程中运行,像访问网络就属于这类任务。因此我们必须要重新开启一个后台线程运行这些任务。然而,往往这些任务最终又会直接或者间接的需要访问和控制ui控件。例如访问网络获取数据,然后需要将这些数据处理显示出来。就出现了上面所说的情况。原本这是在正常不过的现象了,但是android规定除了ui线程外,其他线程都不可以对那些ui控件访问和操控。为了解决这个问题,于是就引出了我们今天的话题。android中后台线程如何与ui线程交互。
据我所知android提供了以下几种 ,用于实现后台线程与ui线程的交互。
1、handler
2、activity.runonuithread(runnable)
3、view.post(runnable)
4、view.postdelayed(runnabe,long)
5、asynctask
一:handler
handler是android中专门用来在线程之间传递信息类的。
要讲明handler的用法非常简单,但是我在这里会少许深入的讲一下handler的运行机制。
为了能够让handler在线程间传递消息,我们还需要用到几个类。他们是looper,messagequeue,message。
这里说的looper可不是前段时间的好莱坞大片环形使者,他的主要功能是为特定单一线程运行一个消息环。一个线程对应一个looper。同样一个looper对应一个线程。这就是所谓的特定单一。一般情况下,在一个线程创建时他本身是不会生产他特定单一的looper的(主线程是个特例)。因此我们需要手动的把一个looper与线程相关联。其 只需在需要关联的looper的线程中调用looper.prepare。之后我们再调用looper.loop启动looper。
说了这么多looper的事情,到底这个looper有什么用哪。其实之前我们已经说到了,他是为线程运行一个消息环。具体的说,在我们将特定单一looper与线程关联的时候,looper会同时生产一个messagequeue。他是一个消息队列,looper会不停的从messagequee中取出消息,也就是message。然后线程就会根据message中的内容进行相应的操作。
那么messagequeue中的message是从哪里来的哪?那就要提到handler了。在我们创建handler的时候,我们需要与特定的looper绑定。这样通过handler我们就可以把message传递给特定的looper,继而传递给特定的线程。在这里,looper和handler并非一一对应的。一个looper可以对应多个handler,而一个handler只能对应一个looper(突然想起了一夫多妻制,呵呵)。这里补充一下,handler和looper的绑定,是在构建handler的时候实现的,具体查询handler的构造函数。
在我们创建handler并与相应looper绑定之后,我们就可以传递message了。我们只需要调用handler的sendmessage函数,将message作为给相应线程。之后这个message就会被塞进looper的messagequeue。然后再被looper取出来交给线程处理。
这里要补充说一下message,虽然我们可以自己创建一个新的message,但是更加推荐的是调用handler的obtainmessage 来获取一个message。这个 的作用是从的消息池中取出一个message,这样就可以避免message创建和销毁带来的资源浪费了(此文来自: 马开东博客
转载请注明出处 网址:
这也就是算得上重复利用的绿色之举了吧)。
突然发现有一点很重要的地方没有讲到,那就是线程从looper收到message之后他是如何做出响应的嘞。其实原来线程所需要做出何种响应需要我们在我们自定义的handler类中的handlemessage重构 中编写。之后才是之前说的创建handler并绑定looper。
好吧说的可能哟点乱,总结一下利用handler传递信息的 。
假设a线程要传递信息给b线程,我们需要做的就是
1、在b线程中调用looper.prepare和looper.loop。(主线程不需要)
2、 编写handler类,重写其中的handlemessage 。
3、创建handler类的实例,并绑定looper
4、调用handler的sentmessage 发送消息。
到这里,我们想handler的运行机制我应该是阐述的差不多了吧,最后再附上一段代码,供大家参考。
1 public class myhandleractivity extends activity {
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.handlertest);
//实现创建handler并与looper绑定。这里没有涉及looper与
//线程的关联是因为主线程在创建之初就已有looper
myhandler=myhandler(myhandleractivitythis.getmainlooper());
textview = (textview) findviewbyid(r.id.textview);
mythread m = new mythread();
new thread(m).start();
class myhandler extends handler {
public myhandler() {
public myhandler(looper l) {
// 必须重写这个 ,用于处理message
public void handlemessage(message msg) {
// 这里用于更新ui
bundle b = msg.getdata();
string color = b.getstring("color");
myhandleractivity.this.textview.settext(color);
class mythread implements runnable {
public void run() {
//从消息池中取出一个message
message msg = myhandler.obtainmessage();
//bundle是message中的数据
bundle b = new bundle();
b.putstring("color", "我的");
msg.setdata(b);
//传递数据
myhandler.sendmessage(msg); // 向handler发送消息,更新ui
参考资料:
/reference/android/os/handler.html
/reference/android/os/looper.html
/reference/android/os/message.html
http://www./dawei/archive//2010259.html
/2010/08/looper-and-handler-in-android.html
http://www./android007/archive//2494766.html
二:activity.runonuithread(runnable)
&这个 相当简单,我们要做的只是以下几步
1、编写后台线程,这回你可以直接调用ui控件
2、创建后台线程的实例
3、调用ui线程对应的activity的runonuithread ,此文来自: 马开东博客
转载请注明出处 网址:
将后台线程实例作为参数传入其中。
注意:无需调用后台线程的start
三:view.post(runnable)
&该 和 二基本相同,只是在后台线程中能操控的ui控件被限制了,只能是指定的ui控件view。 如下
1、编写后台线程,这回你可以直接调用ui控件,但是该ui控件只能是view
2、创建后台线程的实例
3、调用ui控件view的post ,将后台线程实例作为参数传入其中。
四:view.postdelayed(runnabe,long)
该 是 三的补充,long参数用于制定多少时间后运行后台进程&
五:asynctask
asynctask是一个专门用来处理后台进程与ui线程的。通过asynctask,我们可以非常方便的进行后台线程和ui线程之间的交流。
那么asynctask是如何工作的哪。
asynctask拥有3个重要参数
1、params&
2、progress
params是后台线程所需的参数。在后台线程进行作业的时候,他需要外界为其提供必要的参数,就好像是一个用于下载图片的后台进程,他需要的参数就是图片的下载地址。
progress是后台线程处理作业的进度。依旧上面的例子说,就是下载图片这个任务完成了多少,是20%还是60%。这个数字是由progress提供。
result是后台线程运行的结果,也就是需要提交给ui线程的信息。按照上面的例子来说,就是下载完成的图片。
asynctask还拥有4个重要的回调 。
1、onpreexecute
2、doinbackground
3、onprogressupdate
4、onpostexecute
onpreexecute运行在ui线程,主要目的是为后台线程的运行做准备。当他运行完成后,他会调用doinbackground 。
doinbackground运行在后台线程,他用来负责运行任务。他拥有参数params,并且返回result。在后台线程的运行当中,为了能够更新作业完成的进度,需要在doinbackground 中调用publishprogress 。该 拥有参数progress。通过该 可以更新progress的数据。然后当调用完publishprogress ,他会调用onprogressupdate 用于更新进度。
onprogressupdate运行在ui线程,主要目的是用来更新ui线程中显示进度的ui控件。他拥有progress参数。在doinbackground中调用publishprogress之后,就会自动调onprogressupdate
onpostexecute运行在ui线程,当doinbackground 运行完后,他会调用onpostexecute ,并传入result。在onpostexecute 中,就可以将result更新到ui控件上。
明白了上面的3个参数和4个 ,你要做的就是
1、编写一个继承asynctask的类,并声明3个参数的类型,编写4个回调 的内容。
2、然后在ui线程中创建该类(必须在ui线程中创建)。
3、最后调用asynctask的execute ,传入parmas参数(同样必须在ui线程中调用)。
这样就大功告成了。
另外值得注意的2点就是,千万不要直接调用那四个回调 。还有就是一个asynctask实例只能执行一次,否则就出错哦。
以上是asynctask的基本用法,更加详细的内容请参考android官方文档。最后附上一段代码,供大家参考。
1 private class downloadfilestask extends asynctask&url, integer, long&
2 //在这里声明了params、progress、result参数的类型
//因为这里不需要使用onpreexecute回调 ,所以就没有加入该
//后台线程的目的是更具url下载数据
protected long doinbackground(url... urls) {
int count = urls.//urls是数组,不止一个下载链接
long totalsize = 0;//下载的数据
for (int i = 0; i & i++) {
//download是用于下载的一个类,和asynctask无关,大家可以忽略他的实现
totalsize += downloader.downloadfile(urls[i]);
publishprogress((int) ((i / (float) count) * 100));//更新下载的进度
// escape early if cancel() is called
if (iscancelled()) break;
//更新下载进度
protected void onprogressupdate(integer... progress) {
setprogresspercent(progress[0]);
//将下载的数据更新到ui线程
protected void onpostexecute(long result) {
showdialog("downloaded " + result + " bytes");
&有了上面的这个类,接下你要做的就是在ui线程中创建实例,并调用execute ,传入url参数就可以了。
/reference/android/os/asynctask.html
http://www./dawei/archive//2019903.html
这上面的5种 各有优点。但是究其根本,其实后面四种 都是基于handler 的包装。在一般的情形下后面搜索此文相关文章: 中后台线程与UI线程的交互此文来自: 马开东博客
网址: 站长QQ
Android中后台线程与UI线程的交互_博客园相关文章
博客园_总排行榜
博客园_最新
博客园_月排行榜
博客园_周排行榜
博客园_日排行榜初学Android,不理解Handler和线程有什么区别,求教 -Android- TryCatch
>> Content
初学Android,不理解Handler和线程有什么区别,求教
昨天刚看了Handler和HandlerThread这个东西,不明白为什么要用这么复杂的东西,而且Handler直接post的话好像还不是子线程运行。那我再开发的时候直接用Thread行不行?两个有什么区别?
------Solutions------
个人理解handler就是把thread封装了一下,自己实现也可以,但是自己要实现消息传递机制如果不对,楼下的correct&me
------Solutions------
Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行更新设置操作,但是有时候又不能再UI主线程进行一些耗时操作,那样UI会响应很迟钝的,这时候就会新开一个线程,新开的线程可以通过Handler来把处理的结果由消息传回UI主线程,在UI主线程里进行相关的UI更新等等~
------Solutions------
Handler就是android中一个机制,主要是考虑到线程安全的!
------Solutions------
引用&2&楼&listening_music&的回复:Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行更新设置操作,但是有时候又不能再UI主线程进行一些耗时操作,那样UI会响应很迟钝的,这时候就会新开一个线程,新开的线程可以通过Handler来把处理的结果由消息传回UI主线程,在UI主线程里进行相关的UI更新等等~还是有些不明白,意思是如果我自己写一个线程,把UI传进去,那再新线程中是不能操作UI的?另外,如果我不操作UI,只是做一些其他的后台操作,能否用Thread而不用Android提供的Handler?
------Solutions------
引用&4&楼&suolong123&的回复:引用&2&楼&listening_music&的回复:Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行更新设置操作,但是有时候又不能再UI主线程进行一些耗时操作,那样UI会响应很迟钝的,这时候就会新开一个线程,新开的线程可以通过Handler来把处理的结果由消息传回UI主线程,在UI主线程里进行相关的UI更……1。新线程是不能操作UI主线程的2.&如果不操作UI,可以只用Thread
------Solutions------
引用&5&楼&hjue&的回复:引用&4&楼&suolong123&的回复:引用&2&楼&listening_music&的回复:Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行更新设置操作,但是有时候又不能再UI主线程进行一些耗时操作,那样UI会响应很迟钝的,这时候就会新开一个线程,新开的线程可以通过Handler来把处理的结果……灰常感谢!同时期待更精彩答案……
------Solutions------
如果你在UI中起了线程,这时你在线程中做完某些处理后想进行UI的操作(如:更新界面),这时,你有两种方法。1,在线程中直接调用UI中的方法来更新UI,这时会报错,因为Android是非线程安全的,因为子线程在更新UI的同时主线程也可能在更新UI,这样的话因为是非线程安全因此可能会出错,所以Android规定不可在子线程中执行更新UI的操作。2,子线程可以发送消息(sendMessage)给主线程,由主线程自己更新自己,这就用到Android的Handler消息管理机制了。具体Handler的用法网上很多。当然如果线程中没有UI操作那就不需要发送什么消息给主线程了。与Handler完成相同功能的还有AsyncTask,是Android提供的一个异步类,它在执行完线程操作后会直接跳回主线程,用法网上很多。
------Solutions------
纯个人感觉,THREAD一般都是和UI没联系的,HANDLER我个人感觉就是一个桥梁,THREAD读出数据然后send一个message给handler来实现和UI的交互
------Solutions------
引用&8&楼&sh71zpi0&的回复:纯个人感觉,THREAD一般都是和UI没联系的,HANDLER我个人感觉就是一个桥梁,THREAD读出数据然后send一个message给handler来实现和UI的交互我也这么认为,不过感觉还是Thread好用,起码学到现在为止感觉还是会使用Thread,可能学习的不够深吧
------Solutions------
引用&9&楼&suolong123&的回复:引用&8&楼&sh71zpi0&的回复:纯个人感觉,THREAD一般都是和UI没联系的,HANDLER我个人感觉就是一个桥梁,THREAD读出数据然后send一个message给handler来实现和UI的交互我也这么认为,不过感觉还是Thread好用,起码学到现在为止感觉还是会使用Thread,可能学习的不够深吧我原来学的时候啥线程都不会,后来做android一次读大量图片直接把我搞得离死不远了……现在碰见个东西就想线程……
------Solutions------
handler&post仍然是在ui线程中启动,没有启到多线程的作用。你要使用多线程可以直接用Thread&然后thread.start但是HandlerThread是重新启动线程和handler不一样,可以说和thread起到同样的功能
------Solutions------
当你需要做一些比较耗时的动作时,为了防止UI卡住,就要新开一个线程来做.情况1:如果线程里面不需要更改UI,那就随意了.情况2:如果线程里面需要更改UI,那就要用到handler,利用handler传送消息.
------Solutions------
我的理解:理解Handler最好是要结合Looper和MessageQueue。handler的发送message和task只是往某一个looper的MessageQueue注入一项。Looper是和thread结合的,就是一个事件循环。当该线程回到其事件循环时,之前注入的项就会得到执行。至于在哪个线程里执行,要看handler发送到哪个线程的looper了,创建handler时都会绑定一个looper(ui线程是自动绑定的),handler发送的message等都会在该looper的线程得到处理。如果你有Qt的开发经验就很容易理解,这跟Qt的信号槽几乎是如出一辙。
------Solutions------
引用&5&楼&hjue&的回复:引用&4&楼&suolong123&的回复:引用&2&楼&listening_music&的回复:Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行更新设置操作,但是有时候又不能再UI主线程进行一些耗时操作,那样UI会响应很迟钝的,这时候就会新开一个线程,新开的线程可以通过Handler来把处理的结果……认同&,难得见到HY
------Solutions------
http://blog.csdn.net/androidbluetooth/article/details/6384641不是很复杂,推荐你看看上面一篇文章。
------Solutions------
引用&8&楼&sh71zpi0&的回复:纯个人感觉,THREAD一般都是和UI没联系的,HANDLER我个人感觉就是一个桥梁,THREAD读出数据然后send一个message给handler来实现和UI的交互
------Solutions------
引用&4&楼&suolong123&的回复:引用&2&楼&listening_music&的回复:Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行更新设置操作,但是有时候又不能再UI主线程进行一些耗时操作,那样UI会响应很迟钝的,这时候就会新开一个线程,新开的线程可以通过Handler来把处理的结果由消息传回UI主线程,在UI主线程里进行相关的UI更……如果你不需要跟UI线程进行交互的话是可以用thread的啦~
------Solutions------
引用&13&楼&challchampion&的回复:我的理解:理解Handler最好是要结合Looper和MessageQueue。handler的发送message和task只是往某一个looper的MessageQueue注入一项。Looper是和thread结合的,就是一个事件循环。当该线程回到其事件循环时,之前注入的项就会得到执行。至于在哪个线程里执行,要看handler发送到哪个线程的looper了,创建handler时……解释的不错,在我使用当中handler主要是对message发送,接受和处理。不仅仅本身的message,有时候还是其他线程的message。
------Solutions------
引用&6&楼&suolong123&的回复:引用&5&楼&hjue&的回复:引用&4&楼&suolong123&的回复:引用&2&楼&listening_music&的回复:Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行更新设置操作,但是有时候又不能再UI主线程进行一些耗时操作,那样UI会响应很迟钝的,这时候就会新开一个线程,新开的……如其所说}

我要回帖

更多关于 android 线程操作 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信