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主 ...
随机推荐
- B1008 数组元素循环右移问题 (20分)
B1008 数组元素循环右移问题 (20分) 思路 1 2 3 4 5 6 5 6 1 2 3 4 6个数,循环右移2位. 也可以理解为 先翻转 6 5 4 3 2 1 然后再两部分,分别翻转 5 6 ...
- 用python实现【五猴分桃】问题
转载链接:https://blog.csdn.net/cy309173854/article/details/78296839 据说“五猴分桃”问题最先是由大物理学家狄拉克提出来的,这一貌似简单的问题 ...
- 3,MongoDB之数据类型
一.MongoDB 之数据类型 首先我们要先了解一下MongoDB中有什么样的数据类型: Object ID :Documents 自生成的 _id String: 字符串,必须是utf-8 Boo ...
- Altium Designer之模块复用——设备图表符与Snippets
Altium Designer中的设备图表符(Device Sheet Symbol)和Snippets是设计中模块复用的利器,下面简单介绍下这个两个功能的使用. 一.设备图表符(Device She ...
- 3 Mongodb数据查询1
1.基本查询 方法find():查询 db.集合名称.find({条件文档}) 方法findOne():查询,只返回第一个 db.集合名称.findOne({条件文档}) 方法pretty():将结果 ...
- Java-JNA使用心得
自上个月20号,历时整整一个月,终于找到工作入职了. 然后这段时间一直看公司的框架还有业务方面的东西.其实由于给分配了一个研究Java调用C语言接口的问题,导致框架业务方面的东西还不熟,然后现在手上又 ...
- “管中窥豹”,MyCAT的基因缺陷
提起MyCAT,我的脑海里,总是浮现出这样一首偈.弘忍觉得自己老了,需要找一个接班人,于是,弘忍要求弟子们每人写一个偈子,根据偈子观察各位弟子的开悟程度,从而传授正宗禅宗的衣钵.弟子们心里其实都很明白 ...
- .NET非常棒的开源项目,给你意想不到的东西!
http://www.cnblogs.com/Leo_wl/p/4560146.html
- 【Divided Two】cpp
题目: Divide two integers without using multiplication, division and mod operator. If it is overflow, ...
- JMeter学习笔记(六) 文件下载接口测试
本次测试的是文件下载接口,文件是PDF文档,步骤如下: 1.通过jmeter的录制功能,获取了文件下载接口的地址和参数,和其他的HTTP请求一样的配置 2.执行此接口后,察看结果树,点击下载接口的结果 ...