你的位置:首页 > 操作系统

[操作系统]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();    }  }}