网络交互——实现从服务器获取文件(例如:图片)
一 需求:创建一个Tomcat服务器, 实现从Tomcat服务器中获取一张图片显示在界面中
涉及到的问题:
1:Android在4.x版本之后就限制了在主线程不能执行联网操作
会抛出异常
处理方式:
2:子线程不能直接操作界面,所以要用到消息机制Handler
2-1:当子线程在操作界面时抛出异常
3:Handler消息处理机制
实现步骤:
主线程中:
找到组件ImageView
1.1 创建消息处理器,在主线程用于处理子线程发来的消息并且判断唯一标识是否正确
Handler :消息处理机制,一个处理程序允许你发送和线程消息队列中的消息和Runnable对象关联的进程。
public void handleMessage(Message message) 方法:重写该方法实现接收消息,子类必须实现此接收消息。
1.2 点击方法中:
开线程
new Thread(){public void run(){
1.2.1URL获取网络图片
URL:统一资源定位符;统一资源定位符标识一个互联网资源的位置由RFC 1738指定。
1.2.2打开连接OpenConnection()
URLConnection:一个连接到一个网址读写。
HttpURLConnection:HTTP的一个URLConnection(RFC 2616)用于通过网络发送和接收数据。数据可以是任何类型和长度。这个类可以用来发送和接收数据流的数据,其长度不是预先已知的。
1.2.3设置连接超时5秒
urlConnection.setConnectTimeout(5000);1.2.4设置请求方式为get请求,也可以是post
urlConnection.setRequestMethod("GET");
1.2.5判断响应是否成功(只要获取响应对象里面的内容才会向服务器发送请求)getResponseCode():从 HTTP 响应消息获取状态码。例如,就以下状态行来说:
if (urlConnection.getResponseCode() == 200) {
HTTP/1.0 200 OK
HTTP/1.0 401 Unauthorized
将分别返回 200 和 401。如果无法从响应中识别任何代码(即响应不是有效的 HTTP),则返回 -1。
1.2.6获取服务器返回的数据
InputStream inputStream = urlConnection
.getInputStream();
1.2.7把流处理
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
1.2.8发送消息给主线程
Message message = new Message();
message.what = LOAD_DATA_SUCCESS;// 消息的唯一标识
message.obj = bitmap;// 消息携带的数据
mHandler.sendMessage(message);// 送消息给Handler
Message :消息对象,定义包含一个描述和可以发送给处理程序的任意数据对象的消息。这个对象包含了两个额外的int字段和一个额外的对象领域,允许你在很多情况下不用做分配。
}}.start();
1.3
清单文件中加网络权限。
具体代码实现:
1:界面实现:两个组件
Button——设置:getdraw点击方法
ImageView
界面代码:
<Button
android:id="@+id/bt_getdraw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getdraw"
android:text="获取网络图片" />
<ImageView
android:id="@+id/iv_draw"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
2:创建一个Tomcat服务器
3:MainActivity实现代码:
public class MainActivity extends ActionBarActivity {
private ImageView iv;
//自定义的常量
private static final int LOAD_DATA_SUCCESS = 0;
private static final int LOAD_DATA_ERROR = 1;
// 消息处理器,在主线程用于处理子线程发来的消息
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case LOAD_DATA_SUCCESS://加载网络成功
Bitmap bitmap = (Bitmap) message.obj;//获取消息Message
iv.setImageBitmap(bitmap);
break;
case LOAD_DATA_ERROR://加载失败
Toast.makeText(MainActivity.this, "加载失败", 0).show();
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到ImageView组件
iv = (ImageView) findViewById(R.id.iv_draw);
}
public void getdraw(View v) {
new Thread() {
// 开启线程 肯定是子线程
public void run() {
// 图片地址 String pathString =
// "http://localhost:8080/ServerWebTomcat/53452def306f2c0e-612201abc104d959-3ede4290fffccf6cca84481261796c59.jpg";
// 不能直接访问图片地址,要先访问模拟器
// 访问模拟器 192.168.191.1(本机ip地址) 还有一种写法:10.0.2.2
// 如果真机访问Tomcat 有条件:手机与电脑必须在网络中(无线局域网 wifi)
// 端口port:8080
try {
String pathString = "http://192.168.191.1:8080/ServerWebTomcat/53452def306f2c0e-612201abc104d959-3ede4290fffccf6cca84481261796c59.jpg";
// 获取网络图片
URL url = new URL(pathString);
// 打开连接 获取连接对象
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
// 设置连接超时5秒
urlConnection.setConnectTimeout(5000);
// 设置请求方式为get请求
urlConnection.setRequestMethod("GET");
// 判断响应是否成功(只要获取响应对象里面的内容才会向服务器发送请求)
if (urlConnection.getResponseCode() == 200) {
// 获取服务器返回的数据
InputStream inputStream = urlConnection
.getInputStream();
// 把流处理
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
// 发送消息给主线程
Message message = new Message();
message.what = LOAD_DATA_SUCCESS;// 消息的唯一标识
message.obj = bitmap;// 消息携带的数据
mHandler.sendMessage(message);// 送消息给Handler
} else {
alertUserLoadError();
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
/*
* 获取网络图片失败
*/
private void alertUserLoadError() {
// 吐司也是在操作界面
// 所以发送空消息(没有obj对象),将吐司在主线程处理
mHandler.sendEmptyMessage(LOAD_DATA_ERROR);
}
4:manifest清单文件中添加网络权限