网络交互——实现从服务器获取文件(例如:图片)

一   需求:创建一个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清单文件中添加网络权限