Android消息机制入门

接着处理《Android 网络图片查看器》中出现的问题

使用添加子线程,修改原程序:

package com.wuyudong.imagesviewer;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.HttpConnection;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private EditText et_path;
    private ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_path = (EditText) findViewById(R.id.et_path);
        iv = (ImageView) findViewById(R.id.iv);
    }

    public void click(View view) {

        final String path = et_path.getText().toString().trim();
        if (TextUtils.isEmpty(path)) {
            Toast.makeText(this, "图片路径不能为空", 0).show();
        } else {
            new Thread() {
                @Override
                public void run() {
                    // 连接服务器get请求获取图片
                    try {
                        URL url = new URL(path);

                        // 根据url发送http的请求
                        HttpURLConnection conn = (HttpURLConnection) url
                                .openConnection();
                        // 设置请求的方式
                        conn.setRequestMethod("GET");
                        conn.setConnectTimeout(5000);
                        conn.setReadTimeout(5000);
                        conn.setRequestProperty(
                                "User-Agent",
                                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36");
                        int code = conn.getResponseCode();
                        if (code == 200) {
                            InputStream is = conn.getInputStream();
                            Bitmap bitmap = BitmapFactory.decodeStream(is);
                            iv.setImageBitmap(bitmap);
                        } else {
                            Toast.makeText(MainActivity.this, "显示图片失败", 0)
                                    .show();
                        }

                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        Toast.makeText(MainActivity.this, "访问获取图片失败", 0).show();
                    }
                }

            }.start();
        }

    }

}

运行项目后报错:

06-27 19:27:59.613: W/System.err(2471): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

谁创建了view对象,谁才能动修改view。

代码:iv.setImageBitmap(bitmap);目的就是为了修改UI

也即是主线程才可以修改。为了控制多线程修改view同步问题而设定的

修改后的代码如下:

package com.wuyudong.imagesviewer;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.HttpConnection;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.view.Menu;
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 CHANGE_UI = 1;
    protected static final int ERROR = 2;
    private EditText et_path;
    private ImageView iv;

    // 1、主线程创建消息处理器
    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == CHANGE_UI) {
                Bitmap bitmap = (Bitmap) msg.obj;
                iv.setImageBitmap(bitmap);
            } else if (msg.what == ERROR) {
                Toast.makeText(MainActivity.this, "访问获取图片失败", 0).show();
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_path = (EditText) findViewById(R.id.et_path);
        iv = (ImageView) findViewById(R.id.iv);
    }

    public void click(View view) {

        final String path = et_path.getText().toString().trim();
        if (TextUtils.isEmpty(path)) {
            Toast.makeText(this, "图片路径不能为空", 0).show();
        } else {
            new Thread() {
                @Override
                public void run() {
                    // 连接服务器get请求获取图片
                    try {
                        URL url = new URL(path);

                        // 根据url发送http的请求
                        HttpURLConnection conn = (HttpURLConnection) url
                                .openConnection();
                        // 设置请求的方式
                        conn.setRequestMethod("GET");
                        conn.setConnectTimeout(5000);
                        conn.setReadTimeout(5000);
                        conn.setRequestProperty(
                                "User-Agent",
                                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36");
                        // 得到服务器返回的响应码
                        int code = conn.getResponseCode();
                        if (code == 200) {
                            InputStream is = conn.getInputStream();
                            Bitmap bitmap = BitmapFactory.decodeStream(is);
                            // iv.setImageBitmap(bitmap);
                            // TODO:告诉主线程一个消息:帮我更改界面,内容:bitmap
                            Message msg = new Message();
                            msg.what = CHANGE_UI;
                            msg.obj = bitmap;
                            handler.sendMessage(msg);

                        } else {
                            // Toast.makeText(MainActivity.this, "显示图片失败", 0)
                            // .show();
                            Message msg = new Message();
                            msg.what = ERROR;
                            handler.sendMessage(msg);
                        }

                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        // Toast.makeText(MainActivity.this, "访问获取图片失败",
                        // 0).show();
                        Message msg = new Message();
                        msg.what = ERROR;
                        handler.sendMessage(msg);
                    }
                }

            }.start();
        }

    }

}

 

posted @ 2016-06-27 20:12  wuyudong  阅读(427)  评论(0编辑  收藏  举报
Top_arrow