简而言之一些比较耗时的操作不要在主线程中等待,而是实现异步加载,比如那些下载的操作,如果文件小,网速快,可能一下也完了。。要是文件大了,网速不给力,势必拖垮主线程,用户体验也差。于是android中使用handler来处理这些事情。
xml中定义两个button:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:id="@+id/start"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/start"
/>
<Button
android:id="@+id/stop"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/stop"
/>
</LinearLayout>
HanderActivity.java继承自Activity.java
package com.myandroid.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 HanderActivity extends Activity {
/** Called when the activity is first created. */
Button startButton = null;
Button endButton = null;
Handler handler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startButton = (Button)findViewById(R.id.start);
startButton.setOnClickListener(new StartListener());
endButton = (Button)findViewById(R.id.stop);
endButton.setOnClickListener(new EndListener());
System.out.println(Thread.currentThread());
}
class StartListener implements OnClickListener{
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
handler.post(HandlerThread);
}
}
class EndListener implements OnClickListener{
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
handler.removeCallbacks(HandlerThread);
}
}
//匿名内部类一个线程
Runnable HandlerThread = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("HandlerThread is Running......");
System.out.println(Thread.currentThread());
handler.postDelayed(HandlerThread, 3000);
}
};
}
①,当start按钮按下的时候,handler会通过执行代码handler.post(HandlerThread)把HandlerThread线程加入到handler的线程队列中,执行线程的run()方法,
②,在run()方法中,handler.postDelayed(HandlerThread, 3000)再次将线程放入handler队列,设置延时3000ms,这样是整个线程每个3000ms打印出:HandlerThread is Running......
③但是,在这里其实还是在一个线程里面,通过 System.out.println(Thread.currentThread())的输出结果可以看出都是主线程
2,要实现handler异步的
1,Message类
每个消息都有一个队列,队列中存放的就是Message对象,obtainMessage()来获得消息对象。同时,Message对象是用来传递使用的,它能传递两个整型和一个Object,尽量使用Message的arg1与arg2两个整型来传递参数,那样系统消耗最小(API如是说),如果传递数据量比较大,则可以使用setData(Bundle a)的方法,其中的Bundle对象可以粗略的看成是一个Map对象,但它的Key都是String,而value是有限的一些类型,可以再API里查看。
2,Looper类
Looper能够循环滴从消息队列中取得消息,一般通过thread的getLooper()方法获得一个Looper对象
package com.myandroid.handler;
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 MessageLooperHandler extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println("Activity---->"+Thread.currentThread().getName());
//创建一个HandlerThread对象,它是一个线程
HandlerThread handlerThread = new HandlerThread("HandlerThread");
//启动线程
handlerThread.start();
//创建一个MyHandler对象,该对象继承了Handler,从下面的MyHandler类中可以看到,
//调用的是Handler父类的Handler(Looper looper)的构造函数,而这里传进去的Looper对象是从HandlerThread中取得的。
MyHandler myHandler = new MyHandler(handlerThread.getLooper());
//获得消息对象
Message msg = myHandler.obtainMessage();
//把得到的消息对象发送给生成该消息的Handler,即myHandler,
//当myHandler接收到消息后,就会调用其handleMessage的方法来处理消息
msg.sendToTarget();
}
class MyHandler extends Handler{
public MyHandler() {//构造函数
// TODO Auto-generated constructor stub
}
public MyHandler(Looper looper){//构造函数
super(looper);//实现了父类的该构造函数
}
//当这个Handler接收到Message对象的时候,会自动调用这个方法,来对Message对象进行处理
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("Handler---->"+Thread.currentThread().getName());
}
}
}
这时运行MessageLooperHandler这个Activity可以看到:是两个线程了
实现与主线程的分离,从而可以实现多线程和异步处理。