首页 > 代码库 > Android加载网络图片报android.os.NetworkOnMainThreadException异常

Android加载网络图片报android.os.NetworkOnMainThreadException异常

Android加载网络图片大致可以分为两种,低版本的和高版本的。低版本比如4.0一下或者更低版本的API直接利用Http就能实现了:

1.main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >     <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="@string/imagepath" />         <EditText        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="http://10.191.92.7:8080/web/xiaoxiao.jpg"        android:id="@+id/imagepath"/>         <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/button"                 android:id="@+id/button"/>              <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/imageView"/>                </LinearLayout>

 

2.MainActivity.java

package ygc.yxb.image;import ygc.yxb.service.ImageService;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity {    private EditText pathText;    private ImageView imageView;        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        //获得图片路径        pathText=(EditText) this.findViewById(R.id.imagepath);        //获得要显示的imageView        imageView=(ImageView) this.findViewById(R.id.imageView);       //获得button按钮        Button button=(Button) this.findViewById(R.id.button);              //注册button按钮的点击事件       button.setOnClickListener(new ButtonClickListener());            }        private final class ButtonClickListener implements View.OnClickListener{        @Override        public void onClick(View v) {            String path=pathText.getText().toString();            try {                //业务逻辑层:ImageService类的getImage方法用以获取网络图片                byte[] data = http://www.mamicode.com/ImageService.getImage(path);>

3.ImageService.java

package ygc.yxb.service;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import ygc.yxb.utils.StreamTool;public class ImageService {    /**     * 获取网络图片的数据     * @param path 网络图片路径     * @return     */    public static byte[] getImage(String path) throws Exception {                URL url = new URL(path);        HttpURLConnection conn=(HttpURLConnection)url.openConnection();    //基于HTTP协议的连接对象        conn.setConnectTimeout(5000);//5秒        conn.setRequestMethod("GET");//请求方式        //判断请求是否成功        if(conn.getResponseCode()==200){            //定义输入流            InputStream inStream = conn.getInputStream();            return StreamTool.read(inStream);                    }                return null;    }}

4.StreamTool.java 输入流工具类。

package ygc.yxb.utils;import java.io.ByteArrayOutputStream;import java.io.InputStream;public class StreamTool {    /**     * 读取流中的数据     * @param inStream     * @return     * @throws Exception     */    public static byte[] read(InputStream inStream) throws Exception {        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();        byte[] buffer = new byte[1024];        int len = 0;        //如果字节流中的数据不等于-1,就说明一直有,然后循环读出        while( (len=inStream.read(buffer)) !=-1){            //将读出的数据放入内存中            outputStream.write(buffer);                    }        inStream.close();        return outputStream.toByteArray();    }}

5.AndroidManifest.xml 在清单文件配置访问网络的权限。

 <!-- 访问internet权限 -->
   <uses-permission android:name="android.permission.INTERNET"/>

 

而如果4.0或者以上版本的话就不能直接获取图片了,直接获取网络图片就会报出android.os.NetworkOnMainThreadException异常,因为4.0以上访问网络的功能不能发生在主线程中运行,而如果把上面访问方式改为异步操作就不会出现在4.0上访问报出 android.os.NetworkOnMainThreadException异常了。

 如:

new Thread(){
@Override
public void run(){
//你要执行的方法
//执行完毕后给handler发送一个空消息
handler.sendEmptyMessage(0);
}
}.start();

 

//定义Handler对象
private Handler handler =new Handler(){
@Override
//当有消息发送出来的时候就执行Handler的这个方法
public void handleMessage(Message msg){
super.handleMessage(msg);
//处理UI
}
};

Android加载网络图片报android.os.NetworkOnMainThreadException异常