Android中的异步

异步,只是为了任务并发,让运行效率更高。在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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值