android的应用程序都运行在各自的虚拟机中,进程开始的时候会启动一个主线程,因为主线程负责处理ui相关的业务逻辑时间,因此主线程又称Ui线程.而android采用了UI单线程模型,所以主线程只能拿来更新ui,其他的任何耗时的操作都应该放在子线程中,如果做耗时的操作,ui线程就会卡掉,5秒后就会提示用户界面无响应,是否要关掉当前应用.如果在非UI线程直接对ui线程进行操作就会报错:CalledFromWrongThreadException:only the original thread that created a view hierarchy can touch its views.
因为是ui线程是单线程模型,那么就必须有相应的解决方案,来解决更新ui的问题;android就为我们提供了消息循环机制,我们可以利用这个机制来实现线程间的通信,比如更新ui,大概的方式是在子线程中发送一个Message消息,ui接受到消息以后就会处理.而比较常用的方式就是thread+handle.
例如,
package com.itheima.htmlview;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.itheima.htmlview.utils.StreamTools;
public class MainActivity extends Activity {
private EditText et_path;
private TextView tv_content;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
String data = (String) msg.obj;
tv_content.setText(data);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
tv_content = (TextView) findViewById(R.id.tv_content);
}
public void click(View view){
new Thread(){
public void run() {
try {
String path = et_path.getText().toString().trim();
// 1、发送请求
// (1)创建一个URL对象
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// (2)设置请求头信息
conn.setRequestMethod("GET");
conn.setConnectTimeout(3000);
// 2、服务器返回数据
// (1)判断状态码:200 ok,404 没有找到资源、503、509 服务器端错误
int code = conn.getResponseCode();
if(code == 200){
// (2)解析服务器返回的二进制数据,解析成一个字符串
InputStream is = conn.getInputStream();
String data = StreamTools.readStream(is);
// (3)把图片显示在TextView上
Message msg = Message.obtain();
msg.obj = data;
handler.sendMessage(msg);
}else{
Toast.makeText(MainActivity.this, "请输入一个HTML页面的网络地址", 0).show();
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
}