Android Handler使用
1. 介绍
Handler允许向关联线程的消息队列(MessageQueue)发送消息(Message)和可执行对象(Runnable).
每个Handler实例都与某个线程(即创建该Handler的线程)及该线程的消息队列所关联
Handler主要有两种用途
- 调度消息和可执行对象在未来某个时间点的处理
- 在其他线程中执行动作
2. 实例
2.1 基本实例
注意: 实例中myRunnable方法是被UI线程执行
File: activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lineto.testhandler.MainActivity"> <Button
android:id="@+id/start"
android:text="start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/stop"
android:text="stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
File: MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button start;
private Button stop;
private Handler handler;
private Runnable myRunnable; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); start = (Button)findViewById(R.id.start);
stop = (Button)findViewById(R.id.stop); View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Button button = (Button)v;
if (button == start) {
handler.post(myRunnable);
} else if (v == stop) {
handler.removeCallbacks(myRunnable);
}
}
};
start.setOnClickListener(listener);
stop.setOnClickListener(listener); handler = new Handler();
myRunnable = new Runnable() {
@Override
public void run() {
System.out.println("Run method");
handler.postDelayed(myRunnable, 3000);
}
};
}
}
2.2 进度条实例
在该实例中, 分别采用两种方式来实现
一种是runnable方法由UI线程来执行, 另一种是runnable方法由新线程来执行
可以发现第一种会导致界面卡顿, 后面一种才是Handler的正确使用方法
File: activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lineto.handlerprogressbar.MainActivity"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ProgressBar With Handler"
/>
<ProgressBar
android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:visibility="gone"
/>
<Button
android:id="@+id/start"
android:text="Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/stop"
android:text="Stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> </LinearLayout>
File: MainActivity.java
public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
private Button start;
private Button stop;
private Handler handler;
private boolean use_new_thread = true;
private boolean thread_running = false; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); progressBar = (ProgressBar)findViewById(R.id.progressbar);
start = (Button)findViewById(R.id.start);
stop = (Button)findViewById(R.id.stop); final Runnable myRunnable = new Runnable() {
int i = 0;
@Override
public void run() {
do {
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println(e);
}
if (i < 100) {
i += 10;
} else {
i = 0;
}
Message msg = handler.obtainMessage();
msg.arg1 = i;
handler.sendMessage(msg);
} while(thread_running);
}
}; View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v == start) {
Toast toast = Toast.makeText(MainActivity.this, "Start", Toast.LENGTH_SHORT);
toast.show();
progressBar.setVisibility(View.VISIBLE);
if (use_new_thread) {
thread_running = true;
Thread thread = new Thread(myRunnable);
thread.start();
} else {
thread_running = false;
handler.post(myRunnable);
}
}
else if(v == stop) {
Toast toast = Toast.makeText(MainActivity.this, "Stop", Toast.LENGTH_SHORT);
toast.show();
progressBar.setVisibility(View.GONE);
if (use_new_thread) {
thread_running = false;
} else {
handler.removeCallbacks(myRunnable);
}
}
}
}; start.setOnClickListener(listener);
stop.setOnClickListener(listener); handler = new Handler() {
@Override
public void handleMessage(Message msg) {
progressBar.setProgress(msg.arg1);
if (!use_new_thread) {
handler.post(myRunnable);
}
}
}; }
}
3. Looper
Looper是用于给线程添加一个消息队列(MessageQueue), 并且循环等待; 当有消息时会唤起线程来处理消息的类.
UI线程默认包含一个Looper, 所以通常不需要为新线程创建Looper;当为新线程创建Looper后, 通常使用Handler来进行消息交互
下面是一个典型的Looper使用方法
class LooperThread extends Thread {
public Handler mHandler; public void run() {
Looper.prepare(); mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
}; Looper.loop();
}
}
详细的实例参考<Android实战技巧:消息循环与Looper>
4. HandlerThread
HandlerThread是一个拥有Looper的Thread, 然后可以使用该Looper得到一个Handler(一定要在start()方法之后)
需要注意的是程序结束的时候需要退出Looper(quit()/quitSafely())
相关实例参考<Android HandlerThread 完全解析>
5. Message
Message用于在消息循环中通信, 用来发消息给某个Handler, 可以通过Handler的obtainMessage()从消息池中获取一个Message引用;Message常用的方法是赋值, 相关操作查询API即可
参考:
<Android 异步消息处理机制>
<Android中的Handler的机制与用法详解>
Android Handler使用的更多相关文章
- Android Handler leak 分析及解决办法
In Android, Handler classes should be static or leaks might occur, Messages enqueued on the applicat ...
- Android Handler练习
package com.example.myact12; import java.util.Random; import android.support.v7.app.ActionBarActivit ...
- Android Handler简单使用
package com.example.myhandlertest3; import android.os.Bundle; import android.os.Handler; import andr ...
- Android Handler的使用
大家好我们这一节讲的是Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title. 首先我们看一下习惯了Java编程的人,在不知道Handl ...
- [Android]Handler的消息机制
最经面试中,技术面试中有一个是Handler的消息机制,细细想想,我经常用到的Handler无非是在主线程(或者说Activity)新建一个Handler对象,另外一个Thread是异步加载数据,同时 ...
- 详解Android Handler的使用-别说你不懂handler
我们进行Android开发时,Handler可以说是使用非常频繁的一个概念,它的用处不言而喻.本文就详细介绍Handler的基本概念和用法. Handler的基本概念 Handler主 ...
- Android handler Thread 修改UI Demo
/********************************************************************** * Android handler Thread 修改U ...
- Android Handler的简单使用
大家好我们这一节讲的是Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title. 首先我们看一下习惯了Java编程的人,在不知道Handl ...
- 详解Android Handler的使用
我们进行Android开发时,Handler可以说是使用非常频繁的一个概念,它的用处不言而喻.本文就详细介绍Handler的基本概念和用法. Handler的基本概念 Handler主 ...
- 详解Android Handler的使用-别说你不懂handler(转)
我们进行Android开发时,Handler可以说是使用非常频繁的一个概念,它的用处不言而喻.本文就详细介绍Handler的基本概念和用法. Handler的基本概念 Handler主 ...
随机推荐
- 云心出岫——Splay Tree
(多图预警!!!建议在WI-FI下观看) 之前我们谈论过AVL树,这是一种典型适度平衡的二叉搜索树,成立条件是保持平衡因子在[-1,1]的范围内,这个条件已经是针对理想平衡做出的一个妥协了,但依然显得 ...
- perl语言入门总结-第5章-输入输出
读取标准输入 chomp($line = <STDIN>); #去掉后面的换行 while (defined($line = <STDIN>)) { print "I ...
- 微信小程序 | 51,live新课“小程序UI容器组件”的课堂计划
零基础前端自学入门:小程序UI容器组件 这是一节以UI布局.容器组件的使用为主题的live,专注于布局与容器这一个点,努力把这一点讲透.这是继4月22日整体入门live“零基础周末学习小程序开发”之后 ...
- Android getLocationInWindow
参考博客: http://blog.sina.com.cn/s/blog_44d19b500102vpve.html 这篇博客,我看了三遍,终于看懂了.恩,我就喜欢这样不放弃的自己. 1.getLoc ...
- druid sqlparser使用例子
package com.alibaba.druid.bvt.sql.mysql; import java.util.List; import org.junit.Assert; import com. ...
- 《Cracking the Coding Interview》——第18章:难题——题目11
2014-04-29 04:30 题目:给定一个由‘0’或者‘1’构成的二维数组,找出一个四条边全部由‘1’构成的正方形(矩形中间可以有‘0’),使得矩形面积最大. 解法:用动态规划思想,记录二维数组 ...
- 自动化测试学习之路--json、dom编程
1.json: json是JavaScript Object Notation,是一种数据传输格式. 以下程序都是在浏览器的Console下执行的. 创建一个javaScript的对象: var st ...
- 常用模块(time)
import time # data = time.time() # 获取时间戳# data = time.localtime() # 获取操作系统时间,也称本地时间,可传入时间戳# data = t ...
- XPS Enable GPIO on EMIO interface 不见了
按照 <嵌入式系统软硬件协同设计实战指南 -- 基于xilinx Zynq>第九章 zedboard 入门 我一步一步做到9.1.2 (13) 发现 没有 Enable GPOI on ...
- android 自定义控件之下拉刷新源码详解
下拉刷新 是请求网络数据中经常会用的一种功能. 实现步骤如下: 1.新建项目 PullToRefreshDemo,定义下拉显示的头部布局pull_to_refresh_refresh.xml &l ...