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主 ...
随机推荐
- 裸机——wdt
1. 首先晓得看门狗的基本知识 看门狗是带复位功能的定时器,用于在系统跑飞时复位系统. 接下来按照上次的知识对看门狗进行推导 看门狗的关键词是 定时器 复位 定时器 关键是 时间段 中断 时间段 关键 ...
- C++ 无符号整型和整型的区别
在Win 7系统中,short 表示的范围为 - 32767到 32767,而无符号的short表示的范围为0 到 65535,其他类型的同理可推导出来,当然,仅当数字不为负的时候才使用无符号类型. ...
- POJ:1703-Find them, Catch them(并查集好题)(种类并查集)
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 49867 Accepted: 153 ...
- 12-optionBinding
1-创建一个空的dotnet mvc网站 2- 创建appsettings.json文件, 这文件会默认被绑定 { "ClassNo": "1", " ...
- 4x4矩阵键盘 扫描程序
一:不排除第四位异常处理 uchar JuzhenkeyScan() { // P3=0xfe; // temp=P3; // while(temp!=0xfe) // { // temp=P3; / ...
- SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID
如题: SDK location not found. Define location with sdk.dir in the local.properties file or with an AND ...
- C/C++学习笔记--指针(Pointer)
定义指针 一般类型: type_name * var_name; 例如: int _var = 1555; int * _var_addr=&_var; 一般类型数组类:type_name ...
- python 之发送邮件服务[原著] 海瑞博客
Python 发送邮件 使用默认的django的发送邮件,只适用于单邮箱. 作者:海瑞博客 http://www.hairuinet.com/ setting中配置 # send e-mail EMA ...
- day06_01 上节回顾
1.0 extend 扩展方法及"+"的对比 "+"不会改变数组的内容,而extend会改变数组的内容 2.0 sort扩展sorted() a = [1,2, ...
- 牛客练习赛22-E.简单数据结构1(扩展欧拉定理降幂 +树状数组)
链接:E.简单数据结构1 题意: 给一个长为n的序列,m次操作,每次操作: 1.区间加 2.对于区间,查询 ,一直到- 请注意每次的模数不同. 题解:扩展欧拉定理降幂 对一个数p取log(p)次的 ...