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主 ...
随机推荐
- Aizu:0189-Convenient Location
Convenient Location Time limit 1000 ms Memory limit 131072 kB Problem Description 明年毕业的A为就业而搬家.就职的公司 ...
- jdk1.8源码学习笔记
前言: 前一段时间开始学习了一些基本的数据结构和算法,算是弥补了这方面的知识短板,但是仅仅是对一些算法的了解,目前工作当中也并没有应用到这些,因此希望通过结合实际例子来学习,巩固之前学到的内容,思前想 ...
- storm集群安装部署
安装步骤: 搭建Zookeeper集群: 安装Storm依赖库: 下载并解压Storm发布版本: 修改storm.yaml配置文件: 启动Storm各个后台进程. 1. 搭建Zookeeper集群 这 ...
- 网易考拉Android客户端网络模块设计
本文来自网易云社区 作者:王鲁才 客户端开发中不可避免的需要接触到访问网络的需求,如何把访问网络模块设计的更具有扩展性是每一个移动开发者不得不面对的事情.现在有很多主流的网络请求处理框架,如Squar ...
- 滑动菜单栏之开源项目SlidingMenu的使用
一.SlidingMenu简介 相信大家对SlidingMenu都不陌生了,它是一种比较新的设置界面或配置界面的效果,在主界面左滑或者右滑出现设置界面效果,能方便的进行各种操作.很多优秀的应用都采用了 ...
- APP测试工程师面试题:之一
第六题主要流程:编写计划 → 测试用例 → 评审用例 → 执行用例 → 写BUG →测修复情况 → 上线
- 3D U-Net卷积神经网络
3D U-Net这篇论文的诞生主要是为了处理一些块状图(volumetric images),基本的原理跟U-Net其实并无大差,因为3D U-Net就是用3D卷积操作替换了2D的,不过在这篇博文中我 ...
- 解决windows文件名过长无法删除的问题
删除windows文件时,系统提示如下错误: 从网上找到下面的一种方法,顺利解决(原理不清楚),现记录删除方法如下: . 在要删除的文件夹(delete_dir)同级新建一个空文件夹(empty_di ...
- 爬虫:Scrapy10 - Link Extractors
Link Extractors 适用于从网页(scrapy.http.Response)中抽取会被 follow 的链接的对象. Scrapy 默认提供 2 种可用的 Link Extractor,但 ...
- htmlagilitypack解析html
这是个很好的的东西,以前做Html解析都是在用htmlparser,用的虽然顺手,但解析速度较慢,碰巧今天找到了这个,就拿过来试,一切出乎意料,非常爽,推荐给各位使用. 下面是一些简单的使用技巧,希望 ...