Android 应用软件开发(十)Handler使用
使用Handler管理线程
步骤:
1. 申请一个Handler对象
Handler handler = new Handler();
2. 创建一个线程
{继承Thread类或者实现Runnable这个接口}
使用Runnable创建一个内部匿名类对象updateThread(要复写run方法)
3. 使用handler的post方法将线程加入到线程队列中
handler.post(updateThread);
4. 使用handler的removeCallbacks方法移出updateThread线程
注意:如果线程从线程队列中出来被执行后,则队列中就不在有线程
因此如果线程在被执行后没有方法将其再次加入到队列中,则无需使用removeCallbacks
线程走出线程队列有两种情况:
一种是被执行,此时要执行run方法
一种是使用removeCallbacks方法,此时线程不被执行,因此不调用run
5. 使用handler的postDelayed方法延时将线程加入到队列中
handler.postDelayed(updateThread,3000)
下面给出一个简单的代码:
package my.handler; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class HandleruseActivity extends Activity { /** Called when the activity is first created. */ //声明两个控件变量 private Button startButton = null; private Button endButton = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //获取控件对象 startButton = (Button)findViewById(R.id.startButton); endButton = (Button)findViewById(R.id.endButton); // 设置监听器 startButton.setOnClickListener(new startListener()); endButton.setOnClickListener(new endListener()); } class startListener implements OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub // 将线程updateThread加入到线程队列中 handler.post(updateThread); } } class endListener implements OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub // 将线程updateThread移出线程队列 handler.removeCallbacks(updateThread); } } // 申请handler对象 Handler handler = new Handler(); // 创建一个线程,线程被调用时一定是调用其run函数 /* Runnable updateThread = new Runnable(){ public void run(){ System.out.println("UpdateThread"); // 延迟三秒之后将线程updateData加入到线程队列当中 handler.postDelayed(updateThread, 3000); } };*/ // 继承Runnable 或者继承 Thread Thread updateThread = new Thread(){ public void run(){ System.out.println("UpdateThread Thread"); // 延迟三秒之后将线程updateData加入到线程队列当中 handler.postDelayed(updateThread, 3000); } }; }
package progressBar.handler; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; public class ProgressBarHandlerActivity extends Activity { /** Called when the activity is first created. */ private Button startButton = null; private ProgressBar bar = null; int i=0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); startButton = (Button)findViewById(R.id.startButton); bar = (ProgressBar)findViewById(R.id.bar); startButton.setOnClickListener(new startListener()); } class startListener implements OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub bar.setVisibility(View.VISIBLE); handler.post(updateBar); } } // handler内部实现一个匿名内部类,重载消息处理函数 // 当消息从队列中被取出的时候调用handleMessage函数处理消息 // 这样做的好处是使用参数arg1效率比较高 Handler handler = new Handler(){ public void handleMessage(Message msg){ bar.setProgress(msg.arg1); handler.post(updateBar); } }; Thread updateBar = new Thread(){ public void run(){ System.out.println("Begin Thread!"); i=i+1; Message msg = handler.obtainMessage(); msg.arg1=i; try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } // 发送消息,将消息加入到消息队列中 handler.sendMessage(msg); if(i==100) { handler.removeCallbacks(updateBar); } } }; }
注意:用post方法将线程对象放到队列里面执行,并没有开启一个新的线程,而是直接调用线程
对象的run方法,因此并没有实现线程的异步。
解决的办法是先生成一个HandlerThread对象,启动它(start)
使用handlerThread对象的getLooper方法取得其looper对象,注意在此之前必须要start,否则这个
looper是空的
并将looper对象作为参数传递给handler对象,使得这个handler对象绑定到这个Looper所在线程上面
此时需要重写handler类的构造函数,将looper对象传给父类
Looper:类,提供一种循环的从队列当中取得消息的功能,不要自己创建
这样,这个handler就可以循环的从Message消息队列中不断取消息。
下面使用这个办法的代码:
package handler.extr; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; public class HandlerExtrActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 生成一个HandlerThread对象,此对象实现了使用Looper来处理消息队列的功能 HandlerThread handlerThread = new HandlerThread("handler-thread"); // 启动线程 handlerThread.start(); MyHandler myHandler = new MyHandler(handlerThread.getLooper()); Message msg0 = myHandler.obtainMessage(); Bundle b = new Bundle(); b.putInt("age", 25); b.putString("name","xiaocheng"); msg0.setData(b); msg0.arg1=0; // 将消息发送到目标对象,所谓目标对象就是生成该msg对象的handler对象 msg0.sendToTarget(); System.out.println("Activity--->"+Thread.currentThread().getId()); } // 要实现消息的处理则需要继承复写handleMessage方法 // 一旦使用继承,则需要重写构造函数传送Looper参数 class MyHandler extends Handler{ public MyHandler(){ } public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub int age = msg.getData().getInt("age"); String name = msg.getData().getString("name"); System.out.println("handler--->"+Thread.currentThread().getId()); System.out.println("My name is "+name+", and my age is "+age); System.out.println("msg ---- agr1 is "+msg.arg1); try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } super.handleMessage(msg); } } }