Handler的学习
最简单的handleMode
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
text = (TextView) findViewById(R.id.tv_tv);
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == 1001){
//消息发送过来了 更改UI
text.setText("在handler里面更改成功");
}
}
};
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
//用handler发送一个空消息,携带一个what参数
handler.sendEmptyMessage(1001);
}
}).start();
}
});
}
Handler常见发送消息方法
Message.obtain();//这里可以获取到一个Message对象而不用new出来,因为在下层它有个缓存池,如果没有创建,那么会自动创建一个Message对象回来。
handler.sendEmptyMessage(1001);
Message message = Message.obtain();//这里可以获取到一个Message对象
message.what = 1000;
message.arg1 = 1001;
message.arg2 = 1002; //arg 存储int值
message.obj = MainActivity.this;//存储一个对象
handler.sendMessageAtTime(message, SystemClock.uptimeMillis() + 3000);//延迟系统时间+3秒发送消息
handler.sendMessageDelayed(message, 3000);//延迟绝对时间 3秒发送消息
//handler.post(new Runnable(run))
小程序,下载文件,界面的progressbar用Handler来发送消息实时更新进度
package com.example.synnection.handlermode;
import android.nfc.Tag;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class DwonLoadDemo extends AppCompatActivity {
private static final String APP_URL = "http://download.sj.qq.com/upload/connAssitantDownload/upload/MobileAssistant_1.apk";;
private static final String TAG ="DownLoadDemoActivity";
private ProgressBar progressBar ;
/*
异步下载文件更新进度条的步骤
主线程
点击按键
发起下载
开启子线程下载
下载完成后通知主线程
主线程更新进度条
*/
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what ==100){
int currentPro = msg.arg1;
progressBar.setProgress(currentPro);
Log.i(TAG,"更新进度条ing");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 下载文件
downLoad(APP_URL);
}
});
}
private void downLoad(final String appUrl) {
//创建下载路径
// Environment.getExternalStorageDirectory() 获取扩展存储设备的资源路径
String downLoadFolderName = Environment.getExternalStorageDirectory() + File.separator + "123" + File.separator;
//创建文件夹
File file = new File(downLoadFolderName);
//判断文件夹是否存在,不存在则创建
if(!file.exists()){
file.mkdir();
}
//创建文件名
final File appFile = new File(downLoadFolderName+"hello.apk");
//判断文件是否存在,如存在则删除
if(appFile.exists()){
appFile.delete();
Log.i(TAG,"删除成功");
}
if(appFile!=null){
Log.i(TAG,"文件创建成功");
}
/**
* 在子线程中下载文件
*/
new Thread(new Runnable(){
@Override
public void run() {
try {
URL url = new URL(appUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
int fileMaxLength = conn.getContentLength();//获取文件的总长度
InputStream is = conn.getInputStream();//获取输入流
byte[] b = new byte[1024*1024 ];//每次读取大小
int len = 0;//当前的长度
int currentDwonLoadLen = 0;
OutputStream os = new FileOutputStream(appFile);//写入appFile文件中
while ((len =is.read(b)) != -1){
//每次写入b,从下标0,写到len
os.write(b,0,len);
//当前下载的大小
currentDwonLoadLen += len;
//当前进度条的长度
int currentprogress = currentDwonLoadLen*100 /fileMaxLength;
Log.i(TAG,"currentprogress="+currentprogress);
//获取Message对象 发送消息通知UI更新进度条
Message message = handler.obtainMessage();
message.what = 100;
message.arg1 = currentprogress;
handler.sendMessage(message);
//关闭流
os.close();
is.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
做完出现过几个问题。一个读写 网络 权限没加
一个anr 一点击按钮卡死。
因为把 Message message = handler.obtainMessage();放在了子线程外面也就是在while循环外面
每次发送消息都用的同一个message 导致程序anr卡死
讲道理,放while循环里面每次调用的也是同一个message对象,因为下层是用了一个缓存池来保存的,那为什么放外面会anr呢?
暂时没理解
小程序用Handler实现倒计时