handler与anr机制
1. handler
参考资料:http://blog.csdn.net/ly502541243/article/details/52062179/
首先说明Android的两个特性:
1. 只能在主线程中更新UI,子线程不能更新。
2. 在主线程中不能执行需要耗时过长的方法。(如果有耗时长的方法就扔到子线程去)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <EditText android:id="@+id/ed_path" android:text="http://www.itheima.com/uploads/2015/08/198x57.png" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:onClick="getPic" android:text="查看图片" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <ImageView android:id="@+id/iv_pic" android:layout_height="wrap_content" android:layout_width="fill_parent"/> </LinearLayout>
package com.itheima.picviewer; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends Activity { protected static final int SUCCESS = 1; //定义的常量, 用于判断 到底是 何种消息 protected static final int ERROR = 2; EditText ed_path; ImageView iv_pic; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ed_path = (EditText) findViewById(R.id.ed_path); iv_pic = (ImageView) findViewById(R.id.iv_pic); } String path; //handler 翻译过来表示处理器 Handler handler = new Handler(){ public void handleMessage(Message msg) { switch (msg.what) { case SUCCESS: Bitmap bitmap = (Bitmap) msg.obj; iv_pic.setImageBitmap(bitmap); break; case ERROR: //失败 //弹土司 Toast.makeText(MainActivity.this, "对不起, 出错了. ..", 0).show(); System.out.println("==========出错了...."); default: break; } }; }; //点击查看图片 public void getPic(View v){ //http://www.itheima.com/uploads/2015/08/198x57.png path = ed_path.getText().toString(); new Thread(){ public void run() { try { //构建一个 url对象的实例 URL url = new URL(path); //使用当前的url 与服务器建立 器连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置请求的方式 conn.setRequestMethod("GET"); //设置 超时的 时间 为 5 秒 conn.setConnectTimeout(5000); // 200, 302 , 304, 404, 500 int code = conn.getResponseCode(); if(code==200){ //进来则表示 , 成功的 接受到了服务器的 响应的数据, 服务器 响应成功 //这个 in 就代表着 返回的 图片数据 InputStream in = conn.getInputStream(); //如何将流的数据转换成一个 图片呢? // 这个 bitmap 就是代表着 一张图片 . Bitmap bitmap = BitmapFactory.decodeStream(in); //要 将图片 显示 到 ImageView中 //iv_pic.setImageBitmap(bitmap); //通过handler 发消息 --Message //这里 Message.obtain() 避免了 重复 创建 多个 消息, // 达到了 复用 message. 查看源代码 就可以 了解到 .. Message msg = Message.obtain(); msg.obj = bitmap; msg.what=SUCCESS ; handler.sendMessage(msg); }else{ //进来 的话,则说明网络连接 不好使, 也发一个消息, 通知 主线程 给用户 提示 Message msg = Message.obtain(); msg.what=ERROR; handler.sendMessage(msg); } } catch (Exception e) { e.printStackTrace(); Message msg = Message.obtain(); msg.what=ERROR; handler.sendMessage(msg); } }; }.start(); } }
2. ANR机制
Android中 还有 一套 保护机制, 为了提高用户的感受, 如何一个 应用程序 干了某个耗时的事儿,但是这个耗时的事儿又没有被检测
出来,并且 耗时也的确很长, 那么这个时候, 系统还有另外的一套 保护机制.
如果长时间应用程序无任何响应, 那么会报ANR (application not responding ),应用程序无响应.
在android 中不同的组件中, ANR机制 生效的时间 也是不一样的 .
在activity中, ANR生效的 时间 是 5 秒钟
在 service中,ANR生效的 时间 是 10秒钟