1.Android中的异步任务Handler
Handler:Android提供的处理UI界面更新的一套异步机制..可以发送消息和接受消息.
Handler机制涉及到四个类:Message MessageQueue Looper Handler
以生产者消费的模型来说:
Message:产品
MessageQueue: 仓库
Looper: 循环查看仓库是否有消息
Handler:物流(将产品放进仓库—>处理每一个包裹)
注意
1.只有主线程默认有Looper,没个线程仅有一个looper.并且looper是个死循环,在循环里会监视MessageQueue中的消息,如果有就回调Handler中的dispatchMessage去处理消息.
2.具体的使用
Message:(包装成一个消息)
构造方法:
// 不推荐
Message message1 = new Message();
// 消息是存在线程池中的,先看线程池中是否有可重用的消息,重复使用,节省资源
Message message = Message.obtain();
message.arg1 = i + 1;
message.what = 0;
// 将消息发给主线程(原则:主线程执行的操作越少越好)
handler.sendMessage(message);
从网上获取网页内容:
// 布局是一个WebView
public class NetWorkHandler implements Runnable, Handler.Callback {
private String url;
private callBack call;
private Handler handler;
public NetWorkHandler(String url, callBack call) {
this.url = url;
this.call = call;
// 指明是主线程中,handler和主线程中的looper绑定
handler = new Handler(Looper.getMainLooper(), this);
}
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case 0:
call.onSuccess(((String) msg.obj));
break;
case 1:
call.onFail(((Exception) msg.getData().getSerializable("Exception")), msg.getData().getString("text"));
break;
case 2:
call.onFail(((Exception) msg.getData().getSerializable("Exception")), msg.getData().getString("text"));
break;
}
return true;
}
@Override
public void run() {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
int code = connection.getResponseCode();
if (code == 200) {
InputStream is = connection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int length;
byte[] buffer = new byte[102400];
while ((length = (is.read(buffer))) != -1) {
baos.write(buffer, 0, length);
}
String text = baos.toString("UTF-8");
handler.obtainMessage(0, text).sendToTarget();
} else {
RuntimeException e = new RuntimeException("ResponseCode:" + code);
String text = new String("网络错误");
Bundle bundle = new Bundle();
bundle.putString("text", text);
bundle.putSerializable("Exception", e);
Message obtain = Message.obtain(handler, 1);
obtain.setData(bundle);
obtain.sendToTarget();
}
} catch (IOException e) {
String text = new String("IO异常");
Bundle bundle = new Bundle();
bundle.putString("text", text);
bundle.putSerializable("Exception", e);
Message obtain = Message.obtain(handler, 1);
obtain.setData(bundle);
obtain.sendToTarget();
}
}
public interface callBack {
void onSuccess(String text);
void onFail(Exception e, String text);
}
}
测试类:
private String url = "http://www.imooc.com/learn/135";
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
webView = (WebView) findViewById(R.id.main2_web);
new Thread(new NetWorkHandler(url,this)).start();
}
@Override
public void onSuccess(String text) {
webView.loadDataWithBaseURL("http://www.imooc.com/",text,"text/html; charest=UTF-8","UTF-8",null);
}
@Override
public void onFail(Exception e, String text) {
e.printStackTrace();
Toast.makeText(Main2Activity.this, text, Toast.LENGTH_SHORT).show();
}
}
3.Handler和AsyncTask的联系区别
1.首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
2.Handler机制:我们通过Message包装一个消息,通过Handler发送到消息仓库(掌管仓库的是MessageQueue);并且Looper在不时的盯着仓库,是否有消息,如果有就去出来交给Handler再去处理.
3.AsyncTask:AsyncTask异步任务是通过onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)这几个方法;这几个方法.doInBackground()函数在后台执行数据的处理,然后自动调用onProgressUpdate等方法来更新UI界面.
参考文献:
https://changer0.github.io/2016/08/30/Android%E7%AC%94%E8%AE%B0/Day25-Handler%E5%92%8CApplication/