异步,只是为了任务并发,让运行效率更高。在android中有多种方法可以实现异步。
(1)Thread
线程是最简单,最基本的方式。也是其它方式的基础。只需要继承java.lang.Thread,并重写public void run()即可。
public class myThread extends Thread {
private final String TAG=getClass().getName();
private int m_Limit;
public myThread(int Max){
m_Limit=Max;
}
@Override
public void run() {
for (int i = 0; i < m_Limit; i++) {
Log.i(TAG, "Thread Counter ="+i);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行Thread,则需要调用Thread的start()方法。
myThread m_Thread=new myThread(Max);
m_Thread.start();
(2)Runnable
Runnable是一个接口,含有唯一方法public void run()。
需要自定义类来实现这个接口,之后借用Thread的构造函数Thread(Runnable),封装为Thread运行。
实现如下:
public class myRunnable implements Runnable {
private final String TAG=getClass().getName();
private int m_Limit;
public myRunnable(int Max){
m_Limit=Max;
}
@Override
public void run() {
for (int i = 0; i < m_Limit; i++) {
Log.i(TAG, "Runnable Counter ="+i);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行如下:
myRunnable m_Runnable=new myRunnable(Max);
Thread m_RunnableThread=new Thread(m_Runnable);
m_RunnableThread.start();
前两者,唯一的不同是一个采用继承父类,一个采用实现接口。
两者共同的缺点是,不能对UI进行更新,这是由Android的系统设计所决定的。
Android 要求所有的UI操作,必须在主线程完成。否则会报异常。
(3)Handler
Android的异步机制中分为4个角色,分别为Message,MessageQueue,Looper和Handler。
(a)Message是消息载体。Message中有4个字段比较常用。
what,整数型,可用于区分消息类型。
arg1,arg2,整数型,可以用于存储整数信息。
obj,可以存储其它类型信息。
(b)MessageQueue,用于存储所接收到的消息。
(c)Looper,消息的分发者。每当有消息进入MessageQueue,Looper都会dispatch消息给对应的handler。
(d)Handler,即是消息的发送者,又是消息的处理者。
我们可以将handler放入线程,使用Handler.sendMessage(Message)来发送消息。
而在主线程中,使用Handler的public void handleMessage(Message msg)来处理消息。
Handler的实现:
public class myHandler extends Handler {
private final String TAG=getClass().getName();
public static final int MSG_TYPE_ADD=1;
private TextView m_TextView;
private int currentCount=0;
public myHandler(TextView textView){
m_TextView=textView;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MSG_TYPE_ADD:
currentCount+=1;
Log.i(TAG, "Runnable Counter ="+currentCount);
m_TextView.setText(String.valueOf(currentCount));
break;
}
}
}
创建Handler
TextView mc_Handler=(TextView)findViewById(R.id.Show);
myHandler m_Handler=new myHandler(mc_Handler);
消息发送如下:
Thread m_HandlerThread=new Thread(){
@Override
public void run() {
Message msg;
for (int i = 0; i < Max; i++) {
msg=new Message();
msg.what=myHandler.MSG_TYPE_ADD;
m_Handler.sendMessage(msg);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
m_HandlerThread.start();
Handler采用回调的方式解决UI更新的问题。
(4)AsyncTask
其实,不需要了解过多的android异步消息机制。android给提供了更方便的接口,来处理异步的问题,对主线程和子线程的处理进行了封装。
我们需要继承AsynTask类,并对必要的方法进行重写。
AsyncTask是一个抽象类。使用它时,需要制定三个泛型参数。
AsyncTask<Params, Progress, Result>
我们先来看AsyncTask的常用接口.
protected abstract Result doInBackground(Params... var1);
protected void onPreExecute();
protected void onPostExecute(Result result);
protected void onProgressUpdate(Progress... values);
protected final void publishProgress(Progress... values);
(a)doInBackground
doInBackground是必须要实现的。该方法将在子线程中运行,因此不能有UI操作。
注意doInBackground传参类型为Params,即AsyncTask的第一个参数类型。所以Params是给doInBackground的输入类型。
而doInBackground的输出类型为Result,即AsyncTask的第三个参数类型。所以Result为doInBackground的输出类型。
(b)onPostExecute
当Task执行结束时,将调用该方法。注意onPostExecute的传参类型为Result,因此,doInBackground执行结束后,会将结果传递给onPostExecute。onPostExecute在主线程中运行,可以对UI进行操作。
(c)onProgressUpdate
该方法用于更新进度情况,例如显示进度条等。在主线程中运行,可以对UI进行操作。onProgressUpdate方法的传参为Progress类型,即AsyncTask的第二个参数类型。
(d)onProgressUpdate
那么如何触发onProgressUpdate方法呢?在doInBackground中调用publishProgress来更新进度。而publishProgress的传参类型正是Progress类型。
(e)onPreExecute
该方法将在doInBackground前调用,做一些Task的准备工作。
AsyncTask例子如下
public class myAsynTask extends AsyncTask<Integer,Integer,Void> {
private final String TAG=getClass().getName();
private TextView m_TextView;
public void initTask(TextView textview){
m_TextView=textview;
}
@Override
protected Void doInBackground(Integer... values) {
for (int i = 0; i < values[0]; i++) {
publishProgress(i);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
if(m_TextView!=null){
Log.i(TAG, "Asyn Task Counter ="+values[0]);
m_TextView.setText(values[0]);
Log.i(TAG, "onProgressUpdate: ");
}
}
}
AsyncTask的执行
myAsynTask m_AsynTask=new myAsynTask();
m_AsynTask.initTask(mc_AsynTask);
m_AsynTask.execute(Max);