package com.example.handlertest;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

/**
* 通过一个demo来讲解下几种Handler处理的情况
*
*
*
* 为了引入Handler消息机制,我们必须先知道“同步”和“异步”通信的差别
*
* “同步”通信: 比如 我打电话给小明,跟小明进行对话,我必须等到和小明结束通话之后,才能再拨打其他人的电话
* (同步就是发送一个请求之后,什么事都不做,一直等到结果返回后才继续做下面的事情)
*
* "异步"通信: 比如 我给几个同学发送E-mail邮件,全部发送过去之后,不需要在这边等他们回复, 我还可以去做别的事情,他们回复的时候,邮箱系统会通知我
* (异步就是发出请求之后,这个请求完成之后,通过状态,通知或者回调等方式来通知调用者处理的结果)
*
*
* Handler机制的产生原因: 一个应用程序开启之后,首先会开启一个UI线程(主线程),顾名思义是用来管理界面中UI控件的,
* 并对事件进行分发,比如一个Button的点击事件,android把事件分发到对应的Button上,来响应用户操作
* 但由于用户有可能需要做一些耗时的操作(下载文件),但是android如果5秒钟界面没反应的话,就会提示
* 用户关闭应用程序了,所以这时候需要把这些耗时的操作放在 子线程 中处理,子线程处理完成之后再去更新
* UI线程中的界面,而Android的UI线程又是不安全的,这样意味着子线程中无法直接更新UI线程的界面,
* 因此Android中设计了Handler来解决这个问题!
*
* 解决方法: Handler运行在UI线程中,它与子线程可通过Message对象来传递数据,这时候,handler就承担了接收子线程
* 传来的Message对象的责任,从而配合UI线程更新UI。
*
*
* Handler消息机制:
*
*
* 1.handler存取消息的原理:
*
* Handler允许发送并处理Message消息,Message消息通过主线程的MessageQueue消息队列相关联的Message和
* Runnable对象进行存取,当创建一个新的handler时(在主线程中创建),handler就属于当前主线程,主线程的
* MessageQueue也同步创建,Handler会绑定到该主线程/消息队列中,这样,handler就可以通过主线程的消息队列
* 发送和接收Message消息对象了
*
*
* 2.Handler消息处理机制的几种情况[下面用代码来说明这几种情况]: 2.1 button1: 主线程中做Handler 2.2 button2:
* 子线程中做Handler 2.3 button3: 把主线程创建的Handler传递给其他线程完成消息处理 2.4 button4:
* 在其他线程中更新UI线程界面,它抛出异常,我们看看哈~!
*
*
*
* 发送Message不会阻塞线程(异步),而接收消息处理会阻塞线程[当Handler处理完一个Message对象后才会接着去取下一个消息进行处理](同步)
*
*
* 2013年09月11日23:37:08
*
* @author xiaoyaomeng
*
*/

public class MainActivity extends Activity implements OnClickListener {
HandlerDemo myHandlerDemo = null;// 该对象用于主线程中创建handler
Button button1 = null;
Button button2 = null;
Button button3 = null;
Button button4 = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
button4 = (Button) findViewById(R.id.button4);

button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
button4.setOnClickListener(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handlerDealMessage(v.getId());
}

private void handlerDealMessage(int id) {
// TODO Auto-generated method stub
switch (id) {
case R.id.button1: {
// 主线程中创建Handler实例
myHandlerDemo = new HandlerDemo();
Message message = myHandlerDemo.obtainMessage(1,
(Object) ("Hello,My name is Handler1~~"));
message.sendToTarget();// Handler发送消息,会对应发送到这个和这个Handler绑定的UI线程做处理
}
break;
case R.id.button2: {
MyThread myThread = new MyThread();
myThread.start();
}
break;
case R.id.button3: {
myHandlerDemo = new HandlerDemo();
OtherThread otherThread = new OtherThread(myHandlerDemo);
otherThread.start();
}
break;
case R.id.button4: {
errorHandlerThread errorHandlerThread = new errorHandlerThread(
button4);
errorHandlerThread.start();
}
break;
default:
break;
}
}

/*
* MyThread 是内部类,子线程
*/
private class MyThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();

// 1.error: 只能在UI线程中采用不带Looper对象创建Handler对象,所以此处会报异常
// myHandlerDemo = new HandlerDemo();

// 2.error: Looper.myLooper获取的Looper是null,所以也会报异常
// myHandlerDemo = new HandlerDemo(Looper.myLooper());

// 通过Looper.getMainLooper()可以得到父类的looper,所以可以成功创建handler对象并绑定MessageQueue
myHandlerDemo = new HandlerDemo(Looper.getMainLooper());
Message message = myHandlerDemo.obtainMessage(2,
(Object) ("Hello,My name is Handler2~~"));
message.sendToTarget();

}
}

private/**
* 创建一个Handler
*
* @author xiaoyaomeng
*
*/
class HandlerDemo extends Handler {
/* 在UI线程中创建handler时,可以直接调用这个构造函数 */
public HandlerDemo() {
super();
// TODO Auto-generated constructor stub
}

/* 在子线程中创建一个Handler需要用到这个构造函数,否则报错 */
public HandlerDemo(Looper looper) {
super(looper);
// TODO Auto-generated constructor stub
}

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);

switch (msg.what) {
case 1: {
button1.setText(msg.obj.toString());
}
break;
case 2: {
button2.setText(msg.obj.toString());
}
break;
case 3: {
button3.setText(msg.obj.toString());
}
break;
default:
break;

}

}
}
}

/**
*
* 其他线程的类,用来接收一个handler,并在线程中 用这个handler发送消息
*
* @author xiaoyaomeng
*
*/
class OtherThread extends Thread {
private Handler mHandler;

public OtherThread(Handler handler) {
// TODO Auto-generated constructor stub

mHandler = handler;
}

@Override
public void run() {
// TODO Auto-generated method stub
super.run();

Message message = mHandler.obtainMessage(3,
(Object) ("Hello,My name is Handler3~~"));
message.sendToTarget();

}
}

/**
* 测试错误报错的线程
*
* @author xiaoyaomeng
*
*/
class errorHandlerThread extends Thread {

Button button = null;

public errorHandlerThread(Button button) {
// TODO Auto-generated constructor stub
this.button = button;
}

@Override
public void run() {
// TODO Auto-generated method stub
super.run();

button.setText("hahahaha~~~");

}
}

Handler消息机制的一些原理(直接用code讲解)——Android开发的更多相关文章

  1. Android Handler 消息机制原理解析

    前言 做过 Android 开发的童鞋都知道,不能在非主线程修改 UI 控件,因为 Android 规定只能在主线程中访问 UI ,如果在子线程中访问 UI ,那么程序就会抛出异常 android.v ...

  2. Android Handler消息机制源码解析

    好记性不如烂笔头,今天来分析一下Handler的源码实现 Handler机制是Android系统的基础,是多线程之间切换的基础.下面我们分析一下Handler的源码实现. Handler消息机制有4个 ...

  3. 深入理解 Handler 消息机制

    记得很多年前的一次面试中,面试官问了这么一个问题,你在项目中一般如何实现线程切换? 他的本意应该是考察 RxJava 的使用,只是我的答案是 Handler,他也就没有再追问下去了.在早期 Andro ...

  4. Android开发:图文分析 Handler通信机制 的工作原理

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 下面,将图文详解 Handler机制 的工作原理 目录 1. 定义 一套 Android 消息传递机制 2. 作用 在多线程的 ...

  5. Android消息传递之Handler消息机制

    前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...

  6. Handler消息机制与Binder IPC机制完全解析

    1.Handler消息机制 序列 文章 0 Android消息机制-Handler(framework篇) 1 Android消息机制-Handler(native篇) 2 Android消息机制-H ...

  7. Handler消息机制实现更新主UI

    如下实现的是简单的更新主UI的方法,用Handler消息机制 将textview的内容每隔一秒实现num++ /* * handler消息机制 * asynctask异步任务 *  * httpcli ...

  8. Android Handler消息机制不完全解析

    1.Handler的作用 Android开发中,我们经常使用Handler进行页面的更新.例如我们需要在一个下载任务完成后,去更新我们的UI效果,因为AndroidUI操作不是线程安全的,也就意味着我 ...

  9. 源码篇——Handler消息机制

    Handler消息机制 Message 消息 Message.obtain() Message msg = new Message() Handler new Handler(){ handlerMe ...

随机推荐

  1. A - Set of Strings

    Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Description You ar ...

  2. python中panda的dateframe

    1 函数介绍 #to_csv函数的语法#函数原型# to_csv(filepath,sep=",",index=TRUE,header=TRUE)#参数介绍: #(1)导出的文件路 ...

  3. 【Hadoop】HDFS笔记(二):HDFS的HA机制和Federation机制

    HA解决了HDFS的NameNode的单点问题: Federation解决了整个HDFS集群中只有一个名字空间,并且只有单独的一个NameNode管理所有DataNode的问题. 一.HA机制(Hig ...

  4. 【eclipse插件开发实战】Eclipse插件开发2——SWT

    Eclipse插件开发实战2--SWT 一.SWT简介 SWT(StandardWidget Toolkit) 标准小窗口工具箱,一开源的GUI编程框架,与AWT/Swing有相似的用处,eclips ...

  5. 【Linux学习】Vi / Vim编辑器—编辑器工作模式、vi编辑操作

    Vi / Vim编辑器-编辑器工作模式.vi编辑操作 推荐一个很好的学习指南:http://www.oschina.net/translate/learn-vim-progressively 一.编辑 ...

  6. CSS3:nth-child()伪类选择器,Table表格奇偶数行定义样式

    转自爱设计 原文链接http://www.dangshopex.com/jishufenxiang/WEBkaifajishu/8653.html CSS3的强大,让人惊叹,人们在惊喜之余,又不得不为 ...

  7. VR视频原理

    VR视频,这里指的是沉浸式全景视频,基本场景是观影者戴上显示头盔(如cardboard),在其中通过头部的转动可以看到全景视频的每个方向的图像.同时也能听到来自各个方向的声音,声音也会随着头部的转动而 ...

  8. LightOJ 1029 【最小生成树】

    思路: 利用克鲁斯卡尔算法,最小生成树把边从小到大排序,然后Union: 最大生成树就是把边从大到小排序,然后Union: #include<bits/stdc++.h> using na ...

  9. [Xcode 实际操作]九、实用进阶-(20)创建位移关键帧动画:通过添加运动关键点制作位移动画

    目录:[Swift]Xcode实际操作 本文将演示如何通过添加运动关键点的方式,来制作位移动画 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIK ...

  10. 图片美化增强AI接口调用手册

    在调合合AI平台提供的图片美化增强API接口,API平台链接:https://ai.ccint.com/doc/api/crop_enhance_image, 因为有遇到一些问题,写篇博客记录一下 A ...