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()的区别:https://www.oudahe.com/p/24591/
4. 内存泄漏
https://www.oudahe.com/p/24590/
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" 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,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实现线程之间的通信下载文件动态更新进度条,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
总结以上是内存溢出为你收集整理的Handler实现线程之间的通信下载文件动态更新进度条全部内容,希望文章能够帮你解决Handler实现线程之间的通信下载文件动态更新进度条所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)