每一个线程对应一个消息队列 MessageQueue,实现线程之间的通信,可通过 Handler 对象将数据装进 Message 中,再将消息加入消息队列,而后线程会依次处理消息队列中的消息。
初始化:一般使用 Message.obtain() 方法获取一个消息对象,该方法会检查 Message 对象池中是否存在可重复利用的对象,若无,才会 new 一个新对象。
what:相当于 Message 的标识符,区别于其它消息。
arg1、arg2:int 类型,可传递整数。
obj:object 类型,可传递任意对象。
在子线程中可调用主线程的 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
http://www.cnblogs.com/xujian2014/p/5025650.html
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 Studio 教辅 .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;
- }
- }
- }
- }
来源: http://www.cnblogs.com/joahyau/p/7301546.html