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

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://www.jb51.net/article/120624.htm

4. 内存泄漏

http://www.jb51.net/article/120627.htm

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实现线程之间的通信下载文件动态更新进度条,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

时间: 2024-08-01 12:13:41

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

android中实现OkHttp下载文件并带进度条

OkHttp是比较火的网络框架,它支持同步与异步请求,支持缓存,可以拦截,更方便下载大文件与上传文件的操作.下面我们用OkHttp来下载文件并带进度条! 相关资料: 官网地址:http://square.github.io/okhttp/ github源码地址:https://github.com/square/okhttp 一.服务器端简单搭建 可以参考搭建本地Tomcat服务器及相关配置 这篇文章. 新建项目OkHttpServer,在WebContent目录下新建downloadfile目

swing 下载文件时的进度条

Java swing中经常要使用到进度条,比如下载文件和拷贝文件时显示进度,如下图所示:  下载完成之后: 难点在于:在读取输入流的时候,实时更新进度条.  我自己定了一个规则: (1) 若输入流的大小小于1024,则字节数组的长度就是输入流的大小. <!--[if !supportLists]-->(1)      (2) <!--[endif]-->获取文件的大小,并平分为100等份,得到商1: <!--[if !supportLists]-->(2)       

下载文件并显示进度条

  UINT DownloadFile(LPVOID pParam){ CWnd*   pwnd = AfxGetMainWnd(); CProgressCtrl* m_Prog = (CProgressCtrl*)pwnd->GetDlgItem(IDC_PROGRESS1); CButton*  bStart = (CButton*)pwnd->GetDlgItem(IDB_BTN_START);  char    filebuf[512]; CInternetSession netSes

vc 基于对话框多线程编程实例——线程之间的通信

 vc基于对话框多线程编程实例--线程之间的通信 实例:  

VC中利用多线程技术实现线程之间的通信

文章来源:[url]http://www.programfan.com/article/showarticle.asp?id=2951[/url] 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.

android用的handler更新进度条但是显示不出来并且进度条的高不能改总是那么高

问题描述 android用的handler更新进度条但是显示不出来并且进度条的高不能改总是那么高 xml文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layo

Android使用AsyncTask下载图片并显示进度条功能

在Android中实现异步任务机制有两种方式,Handler和AsyncTask.这篇文章给大家介绍Android使用AsyncTask下载图片并显示进度条功能. AsyncTask下载图片并显示下载进度,异步类AsyncTask配合进度条,简练! public class AsyncTaskActivity2 extends Activity { private Button btnDown;//图片框 private ImageView ivImage;//图片URL private sta

php+ajax文件上传进度条

ajax|上传 代码分为以下部分: demo.php - 上传过程处理 PLAIN TEXTPHP: <?php include 'UploadProgressMeter.class.php'; $fileWidget = new UploadProgressMeter(); if ($fileWidget->uploadComplete()) {        // 上传完毕的时候,从iframe发送一个js到主窗口表示一切ok        echo $fileWidget->fin

服务器-我这样做asp.net异步文件上传进度条

问题描述 我这样做asp.net异步文件上传进度条 前台两个请求 1.上传文件的请求 2.获取上传进度的请求 1. $("#ufrm").ajaxSubmit({ url: "ReceivFile.ashx", type: "post", success: function (data) { ... 2. $.ajax({ type: "post", url: "Filepro.aspx", data: {