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主 ...
随机推荐
- Android 拍照或相册选择照片进行显示缩放位图 Demo
拍照后直接使用 BitmapFactory.decodeStream(...) 进行创建 Bitmap 并显示是有问题的. Bitmap 是个简单对象,它只存储实际像素数据,也就是说,即使原始照片已压 ...
- HDFS HA 的 hdfs-site.xml
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licens ...
- PHP代码审计1-审计环境与调试函数
审计环境与调试函数 审计环境 测试环境 常用集成环境:phpStudy.WampServer #不同的操作系统下,漏洞测试的结果也可能不一样 PHP编写工具 EditPlu Notepad++ 代码审 ...
- 3 Mongodb数据查询1
1.基本查询 方法find():查询 db.集合名称.find({条件文档}) 方法findOne():查询,只返回第一个 db.集合名称.findOne({条件文档}) 方法pretty():将结果 ...
- dealloc时取weakself引起崩溃
今天无意这中遇到一个奇怪的崩溃,先上引起崩溃的代码: - (void)dealloc { __weak __typeof(self)weak_self = self; NSLog(@"%@& ...
- 《Cracking the Coding Interview》——第18章:难题——题目10
2014-04-29 04:22 题目:给定一堆长度都相等的单词,和起点.终点两个单词,请从这堆单词中寻找一条变换路径,把起点词变成终点词,要求每次变换只能改一个字母. 解法:Leetcode中有Wo ...
- SQL Server VALUES 使用一记住
VALUES 用得最多,最常见的就是 INSER INOT 表名(列名1,列名2,......) VALUES(值1,值2,......) ------------------------------ ...
- Timer的schedule和scheduleAtFixedRate方法的区别解析
在java中,Timer类主要用于定时性.周期性任务 的触发,这个类中有两个方法比较难理解,那就是schedule和scheduleAtFixedRate方法,在这里就用实例分析一下 (1)sched ...
- ffifdyop
题目地址:http://www.shiyanbar.com/ctf/2036 后台登陆 上来看到这个界面,果断先看一波源代码. 看到是拼接字符串进行sql查询,就想到了注入了. 但是很不幸的是md5( ...
- pytorch下对简单的数据进行分类(classification)
看了Movan大佬的文字教程让我对pytorch的基本使用有了一定的了解,下面简单介绍一下二分类用pytorch的基本实现! 希望详细的注释能够对像我一样刚入门的新手来说有点帮助! import to ...