Android day_07 (图片和源码查看器案例 HttpURLConnection类,Handler,runOnUiThread()的使用)

在Android4.0之后谷歌强制要求连接网络不能在主线程进行访问,所以要开辟子线程来访问网络但是子线程中无法更新ui

所以使用Handler实现从子线程快速跳回主线程的操作。

Android day_07 (图片和源码查看器案例 HttpURLConnection类,Handler,runOnUiThread()的使用)_第1张图片

 

 Android day_07 (图片和源码查看器案例 HttpURLConnection类,Handler,runOnUiThread()的使用)_第2张图片

 1)Handler 和runOnUiThread()的使用

可以进行ui的更新

Android day_07 (图片和源码查看器案例 HttpURLConnection类,Handler,runOnUiThread()的使用)_第3张图片

 final Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
                            //runOnUiThread 不管在哪里调用  action  也就是Runnable()的run()方法中的语句都在运行在UI线程
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                   iv.setImageBitmap(bitmap);
                                }
                            });

2)图片查看器案例 (如何使用图片缓存)

public class MainActivity extends AppCompatActivity {
    private EditText et_path;
    private ImageView iv;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Bitmap bitmap = (Bitmap) msg.obj;
            iv.setImageBitmap(bitmap);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_path = findViewById(R.id.et_path);
        iv = findViewById(R.id.iv);
    }

    //[2]给按钮设置点击事件 查看指定路径图片
    public void click(View v) {
        new Thread() {
            public void run() {
                File file = new File(getCacheDir(), "test.png");
                if (file.exists() && file.length() > 0) {
                    //使用缓存图片
                    System.out.println("使用缓存图片");
                    Bitmap cachebitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
                    //把cachebitmap显示到iv上
                    Message msg = Message.obtain();
                    msg.obj = cachebitmap;
                    handler.sendMessage(msg);
                } else {
                    //第一次访问联网获取数据
                    System.out.println("第一次联网获取图片");
                    try {
                        //[2.1] 获取指定路径
                        String path = et_path.getText().toString().trim();
                        //[2.2] 获取URL对象
                        URL url = new URL(path);
                        //[2.3]获取HttpURLConnection对象
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        //[2.4]设置请求的方式
                        conn.setRequestMethod("GET");
                        //[2.5]设置超时时间
                        conn.setConnectTimeout(5000);
                        //[2.6]获取服务器返回的状态码
                        int code = conn.getResponseCode();
                        if (code == 200) {
                            //[2.7]获取图片数据  以流的形式返还
                            InputStream in = conn.getInputStream();
                            //[2.7.1] 缓存图片 谷歌提供了缓存目录

                            FileOutputStream fos = new FileOutputStream(file);
                            int len = -1;
                            byte[] buffer = new byte[1024];
                            while ((len = in.read(buffer)) != -1) {
                                fos.write(buffer, 0, len);
                            }
                            fos.close();
                            in.close();
                            //[2.8]通过位图工厂把按文件路径获取 Bitmap
                            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());                          
                            //使用 Message的静态方法Message.obtain()获取Message对象可以减少创建对象提高效率
                            Message msg = Message.obtain();
                            msg.obj = bitmap;
                            handler.sendMessage(msg);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }

}

 3) 网页源码查看器案例

public class MainActivity extends AppCompatActivity {
    private EditText et_path;
    private TextView tv_result;
    private final int REQUESTUCESS = 0;
    private final int REQUESTNOTFOUND = 1;
    private final int REQUESTEXCEPTION = 2;
    //在主线程中定义一个Handler
    private Handler handler = new Handler() {
        @Override
        //这个方法在主线程中执行所以就可以在主线程中更新ui了
        public void handleMessage(Message msg) {
            //分类识别消息
            switch (msg.what) {
                case REQUESTUCESS:
                    //将接收到的Message转化成字符串显示在TextView上
                    String content = (String) msg.obj;
                    tv_result.setText(content);
                    break;
                case REQUESTNOTFOUND:
                    Toast.makeText(getApplicationContext(), "无法连接到指定网址", Toast.LENGTH_LONG).show();
                    break;
                case REQUESTEXCEPTION:
                    Toast.makeText(getApplicationContext(), "服务器忙", Toast.LENGTH_LONG).show();
                    break;
            }


        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_path = findViewById(R.id.et_path);
        tv_result = findViewById(R.id.tv_result);
    }

    public void click(View v) {
        //[2.0]创建一个子线程
        new Thread() {
            public void run() {
                try {
                    //[2.1]获取访问路径
                    String path = et_path.getText().toString().trim();
                    //[2.2]获取URL
                    URL url = new URL(path);
                    //[2.3]获取HttpURLConnection的实例  用于发送或接收数据
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    //[2.4]设置发送get请求
                    conn.setRequestMethod("GET");//GET要求大写可以不用写默认为HttpURLConnectionget请求
                    //[2.5]设置请求超时时间
                    conn.setConnectTimeout(5000);
                    //[2.6]获取服务器返回的状态码
                    int code = conn.getResponseCode();
                    //[2.7]对状态码code进行判断
                    if (code == 200) {
                        //[2.8]获取服务器返回的的数据 返回的为一个流
                        InputStream in = conn.getInputStream();
                        //[2.9] 使用定义好的工具类 把流转化成字符串
                        String content = StreamTools.readStram(in);
                        //[2.9.0] 创建Message
                        Message msg = new Message();
                        msg.what = REQUESTUCESS;//标明是哪个消息
                        msg.obj = content;
                        //2.9.1拿着我们创建的handler(助手)在子线程里对系统说要更新ui
                        //发送了一条消息(msg)携带数据这句话执行完我们重写的handleMessage(Message msg)就会执行
                        handler.sendMessage(msg);
                        //[2.9.1] 把数据显示到TextView上
                        //tv_result.setText(content);
                    } else {
                        Message msg = new Message();
                        msg.what = REQUESTNOTFOUND;//标明是哪个消息
                        handler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Message msg = new Message();
                    msg.what = REQUESTEXCEPTION;//标明是哪个消息
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }
}

 

你可能感兴趣的:(Android)