Android开发中的Handler线程初窥,及HandlerThread异步通信的实现
2011-11-21 00:05
573 查看
最近学习Android,学习的时候会用Java的一些机制去理解,但是往往还是有些区别的。
下面我们来看看Android下面的线程使用方法,这里通常会用到Handler。
Handler的作用就是一个队列,先进先出,实现了异步机制。
下面是这个工程的main.xml配置文件:(两个例子的使用同一个xml)
在上面的例子中,Thread使用的是同一个,按照Java的常理应该是不同的,但是这里确实是同一个,大家可以自己测试下。
Handler与主线程是同一线程时,如果程序在设计的时候需要线程初始化较长时间或者下载文件,这种情况下,主线程是出于等待状态的,甚至出现假死现象。
在cmd100.com的视频讲解中,mars老师也讲的很清楚了,我大部分是参考其源代码再做修改。
解决办法是是用HandlerThread类来创建独立于主线程的新线程,实现异步机制,不会影响到主线程的运行。
解决代码如下
下面我们来看看Android下面的线程使用方法,这里通常会用到Handler。
Handler的作用就是一个队列,先进先出,实现了异步机制。
下面是这个工程的main.xml配置文件:(两个例子的使用同一个xml)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ProgressBar android:id = "@+id/bar" style="?android:attr/progressBarStyleHorizontal" android:layout_width = "200dp" android:layout_height = "wrap_content" android:visibility = "gone" /> <Button android:id = "@+id/startButton" android:layout_width = "fill_parent" android:layout_height ="wrap_content" android:text = "start" /> </LinearLayout>
package com.cyl; import android.app.Activity; import android.os.*; import android.widget.*; import android.view.View; import android.view.View.OnClickListener; public class ProgressBarHandler extends Activity { private ProgressBar bar; private Button start; private Handler progressHandler; Runnable progressThread; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //测试当前Activity线程 //打印的结果是: Activity Thread : 1 System.out.println("Activity Thread :" + Thread.currentThread().getId()); bar = (ProgressBar)this.findViewById(R.id.bar); start = (Button)this.findViewById(R.id.startButton); //实现了Handler的内部类 progressHandler = new Handler(){ @Override public void handleMessage(Message msg) { bar.setProgress(msg.arg1); //经过证明Thread均是同一线程。 //打印的结果是: Handler Thread : 1 System.out.println("Handler Thread :" + Thread.currentThread().getId()); progressHandler.post(progressThread); //模拟在90%时停止,removeCallbacks移除线程不能放在Runnable中,否则可能会出现Bug,无法移除。 if(msg.getData().getInt("percent") >= 90){ progressHandler.removeCallbacks(progressThread); } } }; //当在程序启动的时候就调用Handler进行加载处理 //并且线程的执行时间很长,且不可预测,那么程序就会处于一个假死状态 //progressHandler.post(progressThread); start.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { bar.setVisibility(ProgressBar.VISIBLE); progressHandler.post(progressThread); } }); //实现了Runnable的内部类 progressThread = new Runnable(){ int percent = 0; @Override public void run() { percent += 5; //打印的结果是: Runnable Thread : 1 System.out.println("Runnable Thread :" + Thread.currentThread().getId()); //通过Message对象传递参数 Message msg = new Message(); Bundle bundle = new Bundle(); bundle.putInt("percent", percent); msg.setData(bundle); progressHandler.sendMessage(msg); try{ System.out.println("sleep ..."); Thread.sleep(1000); //当在onCreate方法开始就调用progressHandler.post()时,我们设置时间足够长,模拟假死状态。 //主线程处于等待状态,界面无法显示。 //Thread.sleep(10000); System.out.println("wake up..."); }catch(Exception e){ e.printStackTrace(); } } }; } }
在上面的例子中,Thread使用的是同一个,按照Java的常理应该是不同的,但是这里确实是同一个,大家可以自己测试下。
Handler与主线程是同一线程时,如果程序在设计的时候需要线程初始化较长时间或者下载文件,这种情况下,主线程是出于等待状态的,甚至出现假死现象。
在cmd100.com的视频讲解中,mars老师也讲的很清楚了,我大部分是参考其源代码再做修改。
解决办法是是用HandlerThread类来创建独立于主线程的新线程,实现异步机制,不会影响到主线程的运行。
解决代码如下
package com.cyl; import android.app.Activity; import android.os.*; import android.widget.*; import android.view.View; import android.view.View.OnClickListener; public class ProgressBarHandlerThread extends Activity { /** Called when the activity is first created. */ ProgressBar bar; Button start; MyHandler myHandler; Runnable progressThread; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.out.println("Activity Thread :" + Thread.currentThread().getId()); bar = (ProgressBar)this.findViewById(R.id.bar); start = (Button)this.findViewById(R.id.startButton); //使用HandlerThread来实现真正的异步线程,不会与主线程公用线程了。 HandlerThread handlerThread = new HandlerThread("handler_thread"); //使用getLooper()方法之前,先调start()方法 handlerThread.start(); myHandler = new MyHandler(handlerThread.getLooper()); start.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { bar.setVisibility(ProgressBar.VISIBLE); myHandler.post(progressThread); } }); //实现了Runnable的内部类 progressThread = new Runnable(){ int percent = 0; @Override public void run() { percent += 5; //打印的结果是: Activity Thread : 8 System.out.println("Runnable Thread :" + Thread.currentThread().getId()); //通过Message对象传递参数 Message msg = new Message(); Bundle bundle = new Bundle(); bundle.putInt("percent", percent); msg.setData(bundle); myHandler.sendMessage(msg); try{ Thread.sleep(1000); }catch(Exception e){ e.printStackTrace(); } } }; } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { bar.setProgress(msg.arg1); //打印的结果是: MyHandler Thread : 8 System.out.println("MyHandler Thread :" + Thread.currentThread().getId()); myHandler.post(progressThread); if(msg.arg1 >= 90){ myHandler.removeCallbacks(progressThread); } } } }
相关文章推荐
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现。
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现。
- Android开发中的Handler线程初窥,及HandlerThread异步通信的实现
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
- Android开发——多线程使用Handler实现读诗效果
- android学习记录(十一)在非主线程实现更新ui------------Handler
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- 【Android开发】线程与消息处理-通过实现Runnable接口来创建线程
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- 【Android开发】范例2-开启新线程实现电子广告牌
- 【Android开发】线程间通讯机制(基础篇)——Handler、Runnable、HandlerThread、AsyncTask的使用
- Android开发之Service通过Messenger实现线程间的通信
- Android应用开发——线程间通信之Handler+Looper+MessageQueue
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android Handler如何实现线程间通信,源码分析。
- [转]Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面