Android进阶——Handler的实际应用与多线程和界面的四种交互方式

引言

Handler对于多线程有多重要已经,毋须多言,实际上View.post、postDelay、postAtTime等绝大多数的本质都是依赖于Handler机制。

一、Handler的实际应用

前面一篇文章Android进阶——异步不可或缺的组件Handler(一)介绍了Handler的机制及相关知识点,接下来我们就用一个例子来实际使用下Handler。

首先布局文件很简单:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" >
    <TextView  android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Handler的应用——简易图片切换器"/>
    <ImageView  android:id="@+id/id_show_img" android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>
package com.crazymo.styleattrdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import java.util.Timer;
import java.util.TimerTask;

/** * Created by cmo on 16-4-16. */
public class PicBrowserActivity extends Activity {
    private ImageView mImg;
    private int[] imgs=new int[]{
            R.mipmap.ic_blue_launcher,
            R.mipmap.ic_green_launcher,
            R.mipmap.ic_red_launcher,
            R.mipmap.pool_balls_05,
            R.mipmap.ic_toy,
            R.mipmap.ic_launcher
    };
    private int curIndex=0;//当前图片的id
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        mImg= (ImageView) findViewById(R.id.id_show_img);
        final Handler handler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                if(msg.what==0x123){
                    mImg.setImageResource(imgs[curIndex++]);
                    if(curIndex>=5){
                        curIndex=5;
                    }
                }
            }
        };

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                Message msg=new Message();
                msg.what=0x123;
                handler.sendMessage(msg);
            }
        },0,1000);//每隔1s 切换一次
    }
}

二、UI线程与后台交互的四种方式

1、runOnUIThread(Runnable r)

利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程

private Activity mActivity;

mActivity=this;
//从这部分源码可以看到,本质也还是handler
//注意:勿在runOnUiThread(Runnable action)中做耗时操作
public final void More ...runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
           mHandler.post(action);
        } else {
            action.run();
        }
    }
mActivity.runOnUiThread(new Runnable(){    
        @Override
         public void run(){    
             //做UI操作 
         }    
     });    

2、view.post、postDelay、postAtTime

new Thread(new Runnable(){
    @Override
    public void run(){
        //在这里做耗时操作
        mImgv.post(new Runnable(){
            @Override
            public void run(){
                //在这里直接做UI操作
            }
        }).start();
    }
});

3、异步任务

AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程

4、Handler机制

在Handler实现异步时通常涉及到 Handler, Looper, Message,Thread四个角色,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message- àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。

三 延时任务的三种形式

1、利用Handler.CallBack和sendEmptyMessageDelayed

延时跳转

//延时跳转方式1:利用Handler
        new Handler(new Handler.Callback() {
            //当接收到信息之后,会自动触发回调里的handleMessage处理接收到的消息
            @Override
            public boolean handleMessage(Message msg) {
                    //启动直接跳转到MainActivity
                    startActivity(new Intent(WelcomeActivity.this,MainActivity.class));
                finish();
                return false;
            }
        }).sendEmptyMessageDelayed(0,2500);//延时2.5s发送空消息,即延时2.5s再去处理handleMessage里方法

2、view.postDelayed(Runnable…)

new Handler().postDelayed(new Runnable(){
    @Override
    public void run(){
        startActivity(new Intent(WelcomeActivity.this,GuideActivity.class));
    }
},3000);//延时3s跳转

3、利用 Handler.postDelayed(runnable,time)传递Runnable 对象

private Handler handler = new Handler();  

    private Runnable myRunnable= new Runnable() {    
        public void run() {  

            if (run) {  
                handler.postDelayed(this, 3000);  
            }  
            startActivity(new Intent(WelcomeActivity.this,GuideActivity.class));  
        }  
    };

调用触发

handler.post(myRunnable);
handler.post(myRunnable,time);

4、利用TimerTask,继承TimerTask重写run方法

class StartTask extends TimerTask{
        @Override
        public void run() {
            startActivity(new Intent(WelcomeActivity.this,GuideActivity.class));
        }
    }

执行定时任务

//延时跳转2:利用timerTask
Timer timer=new Timer();
timer.schedule(new StartTask(), 2500);//延时2.5s执行任务的方法

你可能感兴趣的:(多线程,异步,handler,定时延时任务,UI操作)