1. 原理

每一个线程对应一个消息队列MessageQueue,实现线程之间的通信,可通过Handler对象将数据装进Message中,再将消息加入消息队列,而后线程会依次处理消息队列中的消息。

2. Message

初始化:一般使用Message.obtain()方法获取一个消息对象,该方法会检查Message对象池中是否存在可重复利用的对象,若无,才会new一个新对象。

what:相当于Message的标识符,区别于其它消息。

arg1、arg2:int类型,可传递整数。

obj:object类型,可传递任意对象。

3. 发送消息

在子线程中可调用主线程的handler.sendMessage(msg)进行发送消息,经过一系列方法调用,会触发handler的handleMessage方法,从而进行消息处理。

发送消息的主要方法:

handler.sendMessage(Message msg);
handler.sendMessageAtTime(Message msg, int time);
handler.sendMessageDelayed(Message msg, int time);

sendMessageAtTime()和sendMessageDelayed()区别在于前者是在指定时间发送消息,可配合SystemClock.uptimeMillis()使用;而后者则是延时发送消息。

除了SendMessage()方法以外,还可以通过post()方法发送消息:

handler.post(Runnable r);
handler.postDelayed(Runnable r, int time);

sendMessage()与post()的区别:http://blog.csdn.net/u013168615/article/details/47024073

4. 内存泄漏

http://www.cnblogs.com/xujian2014/p/5025650.html

5. 通过Handler对象实现下载文件动态更新进度条

AndroidManifest加入权限声明:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

布局:

<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"
tools:context="com.studying.network.DownloadActivity"> <ProgressBar
android:id="@+id/progress_bar"
style="?android:progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" /> <Button
android:id="@+id/download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/download" /> </LinearLayout>

Activity:

public class DownloadActivity extends Activity {

    private static final int DOWNLOAD_MESSAGE_CODE = 100001;
private static final int DOWNLOAD_MESSAGE_FAIL_CODE = 100002;
private static final String APP_URL = "http://clfile.imooc.com/class/assist/119/1328281/Android%20Studio%20教辅%20.pdf";
private MyHandler mHandler;
private ProgressBar mProgressBar; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download); findViewById(R.id.download).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开启子线程
new Thread(new Runnable() {
@Override
public void run() {
download(APP_URL);
}
}).start();
}
});
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mHandler = new MyHandler(this);
} private void download(String appUrl) {
try {
URL url = new URL(appUrl);
URLConnection conn = url.openConnection(); InputStream in = conn.getInputStream();
int contentLength = conn.getContentLength();//获取文件总大小 String downloadPath = Environment.getExternalStorageDirectory() + File.separator + "imooc" + File.separator;
File file = new File(downloadPath);
if (!file.exists()) {
file.mkdir();
} String fileName = downloadPath + "test.pdf";
File apkFile = new File(fileName);
if (apkFile.exists()) {
apkFile.delete();
} int downloadSize = 0;//记录已经下载的大小
byte[] bytes = new byte[1024];
int length = 0; OutputStream out = new FileOutputStream(fileName);
while ((length = in.read(bytes)) != -1) {
out.write(bytes, 0, length);
downloadSize += length; Message msg = Message.obtain();
msg.obj = downloadSize / contentLength * 100;//progress的值为0到100,因此得到的百分数要乘以100
msg.what = DOWNLOAD_MESSAGE_CODE;
mHandler.sendMessage(msg);
} in.close();
out.close(); } catch (IOException e) {
notifyDownloadFailed();
e.printStackTrace();
}
} private void notifyDownloadFailed() {
Message msg = Message.obtain();
msg.what = DOWNLOAD_MESSAGE_FAIL_CODE;
mHandler.sendMessage(msg);
} private static class MyHandler extends Handler{ private WeakReference<DownloadActivity> weakReference; MyHandler(DownloadActivity activity) {
this.weakReference = new WeakReference<>(activity);//以弱引用的形式传递Activity,避免内存泄漏
} @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
DownloadActivity activity = weakReference.get();
//消息处理
switch (msg.what) {
case DOWNLOAD_MESSAGE_CODE:
activity.mProgressBar.setProgress((Integer) msg.obj);
break;
case DOWNLOAD_MESSAGE_FAIL_CODE:
Toast.makeText(activity, "下载失败!", Toast.LENGTH_SHORT).show();
break;
}
}
}
}

Handler实现线程之间的通信-下载文件动态更新进度条的更多相关文章

  1. AsyncTask用法解析-下载文件动态更新进度条

    1. 泛型 AysncTask<Params, Progress, Result> Params:启动任务时传入的参数,通过调用asyncTask.execute(param)方法传入. ...

  2. 通过HttpUrlConnection下载文件并显示进度条

    实现效果: 核心下载块: int count = 0; URL url = new URL("http://hezuo.downxunlei.com/xunlei_hezuo/thunder ...

  3. WPF多线程下载文件,有进度条

    //打开对话框选择文件         private void OpenDialogBox_Click(object sender, RoutedEventArgs e)         {     ...

  4. 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具

    转载:http://blog.csdn.net/mfcing/article/details/43603525 转载:http://blog.csdn.net/infoworld/article/de ...

  5. C# Winform下载文件并显示进度条

    private void btnDown_Click(object sender, EventArgs e) { DownloadFile("http://localhost:1928/We ...

  6. Winform下载文件并显示进度条

    本来是要研究怎样判断下载完成,结果找到这个方法,可以在这个方法完成之后提示下载完成. 代码如下: using System; using System.Collections.Generic; usi ...

  7. iOS边练边学--多线程介绍、NSThread的简单实用、线程安全以及线程之间的通信

    一.iOS中的多线程 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块) iOS中多线程的实现方案有以下几种 二.NSThread线程类的简单实用(直接上代码 ...

  8. Android笔记(三十一)Android中线程之间的通信(三)子线程给主线程发送消息

    先看简单示例:点击按钮,2s之后,TextView改变内容. package cn.lixyz.handlertest; import android.app.Activity; import and ...

  9. Thread线程源码解析,Java线程的状态,线程之间的通信

    线程的基本概念 什么是线程 现代操作系统在运行一个程序的时候,会为其创建一个进程.例如,启动一个Java程序,操作系统就会创建一个Java进程.线代操作系统调度的最小单位是线程.也叫做轻量级进程.在一 ...

随机推荐

  1. 手把手教你从基础学习JQuery

    JQuery JQuery 语法 1.jQuery("选择器").action();通过选择器调用事件函数 但jQuery中,jQuery可以用$代替,即$("选择器&q ...

  2. memcache常用命令

    一.memcached的基本命令(安装.卸载.启动.配置相关): -p 监听的端口 -l  连接的IP地址, 默认是本机   -d start 启动memcached服务 -d restart 重起m ...

  3. PHP基础入门(四)---PHP数组实用基础知识

    PHP数组 数组是特殊的变量,它可以同时保存一个以上的值. ***关键词:数组基础.数组遍历.超全局数组.数组功能.数组函数. 下面来和大家分享一下有关PHP的数组基础知识,希望对你PHP的学习有所帮 ...

  4. PDO数据库操作类

    <?php include 'common_config.php'; /** * Class Mysql * PDO数据库操作类 */ class Mysql { protected stati ...

  5. Chapter 4. The MPEG-4 and H.264 Standards

    本章节介绍一些关于MPEG-4标准与H.264标准的基本知识 比较重要的是第95页关于两种标准的对比表格.其他部分没有什么特别重要的细节.

  6. 【Android Developers Training】 57. 在UI线程之外处理图像

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. Ubantu 16.4 samba安装配置

    本文总结了Ubantu 16.04 环境下的samba安装.配置及使用.本文为原创,也是我的第一篇博客,以后会经常写博客,记录自己的学习.总结及研究,让博客见证着我成长的轨迹. 下文中的所有命令均使用 ...

  8. win10下安装python

    1. 在官网下载python:https://www.python.org/ftp/python/3.5.2/python-3.5.2-amd64.exe 这里下载的是3.5.2版. 2. 双击exe ...

  9. vue--指令中值得随笔的地方

    v-model-- 双向数据绑定 number修饰指令 <!DOCTYPE html> <html lang="en"> <head> < ...

  10. doPost或doGet调用出错(状态代码为405) : HTTP method GET is not supported by this URL

    最近做servlet发现了个问题,解决办法记下来: Servlet  eroor:HTTP method GET is not supported by this URL 错误提示: type: St ...