本文出自:http://blog.csdn.net/dt235201314/article/details/73823653

一丶概述

本周的学习计划是Android通信模块,内容:单线程,多线程通信方式,Handler 与UI Thread的交互,Handler接合子线程的使用。

二丶效果演示(源码链接见文末)


三丶实现功能

1.演示使用Handler常见崩溃

2.handler更新TextView的UI

3.实现图片轮播及停止

4.输出handleMessage(Message mes)的mes打印

5.自定义线程相关handler测试执行

6.Handler异步消息处理测试

handler相关方法运用

四丶正文

1.选说说多线程(工作到现在用的不太多,都是别人封装好的框架直接用)

入门文章 菜鸟教程:Java多线程编程

2.Handler

最初学习Handler是通过扣丁学堂,之前的文章:扣丁学堂——Handler

后面在开发扣丁音乐闪屏页面延时跳转功能时也有用到Handler。文章链接:扣丁音乐(一)——闪屏页SplashActivity(欢迎界面)

最近开发用到的SwipeRefreshLayout 的onRefresh()方法,也常看到handler

@Overridepublic void onRefresh() {    new Handler().postDelayed(new Runnable() {        @Override        public void run() {            mEntities.clear();            intData();            //★3.通知recycleView改变了数据            homeAdapter.notifyDataSetChanged();            //★4.记得关闭刷新,否则刷新球一直在转            mSwipeRefreshLayout.setRefreshing(false);        }    }, 50);}
以上基本是在整理文章前关于handler的所有运用。

好了,现在重新认识

2.Handler类的引入:

3.Handler的执行流程图:

流程图解析: 
相关名词

  • UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的MessageQueue;
  • Handler:作用就是发送与处理信息,如果希望Handler正常工作,在当前线程中要有一个Looper对象
  • Message:Handler接收与处理的消息对象
  • MessageQueue:消息队列,先进先出管理Message,在初始化Looper对象时会创建一个与之关联的MessageQueue;
  • Looper:每个线程只能够有一个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理!

简单点说:

当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送信息;而我们发送的信息会先到主线程的MessageQueue进行等待,由Looper按先入先出顺序取出,再根据message对象的what属性分发给对应的Handler进行处理!



4.Handler的相关方法:

  • void handleMessage(Message msg):处理消息的方法,通常是用于被重写!
  • sendEmptyMessage(int what):发送空消息
  • sendEmptyMessageDelayed(int what,long delayMillis):指定延时多少毫秒后发送空信息
  • sendMessage(Message msg):立即发送信息
  • sendMessageDelayed(Message msg):指定延时多少毫秒后发送信息
  • final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息 
    如果是参数为(int what,Object object):除了判断what属性,还需要判断Object属性是否为指定对象的消息

5.看代码

1.非UI线程线程更新UI崩溃测试:

case R.id.id_btn1:    new Thread() {        @Override        public void run() {            try {                Thread.sleep(1000 * 3);                idTv.setText("蹦啦");            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }.start();    break;case R.id.id_btn2:    new Thread() {        @Override        public void run() {            try {                Thread.sleep(1000 * 3);                handler.post(new Runnable() {                    @Override                    public void run() {                        idTv.setText("又长帅了");                    }                });            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }.start();    break;

关于这里有个小插曲,涉及源码解读,观看爱哥博客

为什么我们可以在非UI线程中更新UI


2.循环播放图片及停止

Handler handler = new Handler();Thread myThread = new Thread(){    @Override    public void run() {        index++;        index = index%3;        System.out.println(index);        idImg.setImageResource(images[index]);        handler.postDelayed(myThread,1000);    }};
点击事件

case R.id.id_btn3:    handler.postDelayed(myThread,1000);    break;case R.id.id_btn4:    handler.removeCallbacks(myThread);

handler.postDelayed(X,X)是延迟执行线程

handler.removeCallbacks(X)移除线程中所有消息和回调


3.handle传递message可携带的内容有(int 实体内等)

Handler customHander = new Handler() {    @Override    public void handleMessage(Message msg) {        idTv.setText("msg.arg1>"+msg.arg1+ "\nmsg.arg2>" +msg.arg2 +"\nmsg.obj>"+((Person)msg.obj).toString());    }};
点击事件

            case R.id.id_btn5:                Person dog=new Person("金三胖",1);//                Message message = new Message();                Message message= customHander.obtainMessage();                message.arg1 = 1;                message.arg2 = 2;                message.obj = dog;//                customHander.sendMessage(message);                message.sendToTarget();                break;

4.消息拦截测试

Handler interceptHander = new Handler(new Handler.Callback() {    @Override    public boolean handleMessage(Message msg) {        Toast.makeText(HandlerDemoActivity.this, "callback handleMessage", Toast.LENGTH_SHORT).show();        System.out.println("is intercept Handler>"+msg.what);        // 设置true拦截消息        return true;    }}){    @Override    public void handleMessage(Message msg) {        System.out.println("is intercept Handler");    }};
点击事件

case R.id.id_btn6:    interceptHander.sendEmptyMessage(1);    break;
5.子线程中实例化hangler崩溃测试

  case R.id.id_btn7:                new Thread() {                    @Override                    public void run() {                        try {                            Thread.sleep(1000*3);//                    idTv.setText("UI线程更新UI会出现什么异常呢?");                            new Handler().post(new Runnable() {                                @Override                                public void run() {                                    idTv.setText("又蹦啦");                                }                            });                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                }.start();                break;
6.自定义一个与线程相关Handler

public class HandlerActivity extends AppCompatActivity {    private MyThread myThread;    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            System.out.println("UI ==:"+ Thread.currentThread());        }    };    class MyThread extends Thread {        public Handler handler;        @Override        public void run() {            Looper.prepare();            handler= new Handler(){                @Override                public void handleMessage(Message msg) {                    System.out.println("currentThread:=="+ Thread.currentThread());                }            };            Looper.loop();        }    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_handler);        myThread = new MyThread();        myThread.start();        try {            Thread.sleep(1000*5);        } catch (InterruptedException e) {            e.printStackTrace();        }        myThread.handler.sendEmptyMessage(1);        handler.sendEmptyMessage(1);    }}
效果打印:

06-29 17:07:30.519 9652-11848/com.example.jinboy.codertodeveloperbytcler I/System.out: currentThread:==Thread[Thread-9681,5,main]
06-29 17:07:30.659 9652-9652/com.example.jinboy.codertodeveloperbytcler I/System.out: UI ==:Thread[main,5,main]


7.Handler异步消息处理

public class HandlerThreadActivity extends AppCompatActivity implements View.OnClickListener {    private Button idBtn1,idBtn2;    private Handler threadhandler;    private HandlerThread thread;    Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            System.out.println("UI thread==>" + Thread.currentThread());            // 给主线程发送消息            Message message = new Message();            message.what =1;            threadhandler.sendMessageDelayed(message, 1000);        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_handler_thread);        idBtn1 = (Button) findViewById(R.id.id_btn1);        idBtn2 = (Button) findViewById(R.id.id_btn2);        idBtn1.setOnClickListener(this);        idBtn2.setOnClickListener(this);        thread = new HandlerThread("Handler Thread");        thread.start();        threadhandler = new Handler(thread.getLooper()) {            @Override            public void handleMessage(Message msg) {                // 处理耗时操作                System.out.println("current thread==>" + Thread.currentThread());                // 给主线程发送消息                Message message = new Message();                message.what =1;                handler.sendMessageDelayed(message, 1000);            }        };//        threadhandler.sendEmptyMessage(1);    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.id_btn1:                handler.sendEmptyMessage(1);                break;            case R.id.id_btn2:                handler.removeMessages(1);                threadhandler.removeMessages(1);                break;        }    }}
打印输出


五丶参考链接和拓展学习

参考内容:

小猪博客:http://my.csdn.net/zpj779878443

慕课网课程-Android面试常客Handler详解

Android异步消息处理机制完全解析-Handler详解

拓展学习:

40个Java多线程问题总结

android进行异步更新UI的四种方式

Handler源码解析

HandlerThread的使用以及原理

Android HandlerThread 完全解析

Android异步消息处理机制完全解析,带你从源码的角度彻底理解

六丶日常开发案例

1.Android避免在主线程进行网络请求和UI操作

方法一:线程请求网络+Handler更新UI

//handler 处理返回的请求结果handler = new Handler() {    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        Bundle data = msg.getData();        String val = data.getString("value");        tv_name.setText(tvName);        tv_originalArticleNumber.setText(tvOriginalArticleNumber);        tv_visitNumber.setText(tvVisitNumber);        tv_mark.setText(tvMark);        tv_rank.setText(tvRank);        Log.i("mylog", "请求结果-->" + val);    }};//新线程进行网络请求Runnable runnable = new Runnable() {    @Override    public void run() {        BlogAuthor blogAuthor = JsoupUtil.getBlogAutoMessage();        tvName = blogAuthor.getAuthorName() + "\n" + blogAuthor.getCode()                + "\n" + blogAuthor.getMyHelloWorld();        tvOriginalArticleNumber = blogAuthor.getOriginalArticleNumber();        tvVisitNumber = blogAuthor.getVisitNumber();        tvMark = blogAuthor.getMark();        tvRank = blogAuthor.getRank();        Message msg = new Message();        Bundle data = new Bundle();        data.putString("value", "请求结果");        msg.setData(data);        handler.sendMessage(msg);    }};new Thread(runnable).start();  //启动子线程
方法二:强制在UI线程更新UI请求网络

setContentView(R.layout.activity_main);if (android.os.Build.VERSION.SDK_INT > 9) {    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();    StrictMode.setThreadPolicy(policy);}

源码下载欢迎Star(updating):https://github.com/JinBoy23520/CoderToDeveloperByTCLer




更多相关文章

  1. Android开场屏 (Splash Screen)
  2. android sqlite遇到的一个吐血的问题
  3. Android源码探究:Android(安卓)Java层消息机制完全解析
  4. Android线程间的通信
  5. 怒刷Android面试100题,再也不担心不能吊打面试官了
  6. Android消息推送机制
  7. Android面试题(基础部分1)
  8. android中asynctask和thread的区别?
  9. Android通讯录管理(获取联系人、通话记录、短信消息)(三)

随机推荐

  1. Android(安卓)开发入门-使用 Intent 在活
  2. android编辑时遇到:{"kind":"error","text
  3. Android检查手机上是否安装了第三方软件
  4. Android(安卓)kotlin 自定义View 旋转、
  5. Android(安卓)Zygote进程和SystemServer
  6. android学习小结5
  7. 2021-02-03
  8. 解决小米手机不能运行Android(安卓)Studi
  9. Android(安卓)显示网络信息 Connectivity
  10. Android(安卓)OTA升级详细流程分析(non-AB