Android连接网络异常:android.os.NetworkOnMainThreadException

package com.ccl.getimage;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.TextUtils;
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 getImage(View view){
		String path = et_path.getText().toString().trim();
		if(TextUtils.isEmpty(path)){
			Toast.makeText(this, "地址不能为空", 0).show();
			return;
		}
		try {
			URL url = new URL(path);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setReadTimeout(5000);
			System.out.println("响应码是--"+conn.getResponseCode());
			if(conn.getResponseCode()==200){

				//获取服务器返回的流数据
				InputStream in = conn.getInputStream();
				//将返回的流数据解析成图片
				Bitmap bitmap = BitmapFactory.decodeStream(in);
				//显示图片
				iv.setImageBitmap(bitmap);
				in.close();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

Android模拟器版本4.1.2

异常解释:在主线程中的网络异常

原因:Android2.3版本后不允许在主线程中直接请求网络获取数据

解决方法(两种):

一:onCreate方法中加入如下代码(不推荐使用,有可能阻塞Android主线程)

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

二:使用Android 的handler机制,另外开启一个子线程请求网络获取数据(推荐使用)

package com.ccl.getimage;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
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;
	private String path;

	//使用Handler更新主线程(UI线程)
	private Handler handler = new Handler(){
		public void handleMessage(Message msg) {
			Bitmap bitmap = (Bitmap) msg.obj;
			iv.setImageBitmap(bitmap);
		};
	};

	@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 getImage(View view){
		path = et_path.getText().toString().trim();
		if(TextUtils.isEmpty(path)){
			Toast.makeText(this, "地址不能为空", 0).show();
			return;
		}
		new Thread(){
			public void run(){
				try {
					URL url = new URL(path);

					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			        conn.setRequestMethod("GET");
			        conn.setReadTimeout(5000);
					System.out.println("响应码是--"+conn.getResponseCode());
					if(conn.getResponseCode()==200){
						//获取服务器返回的流数据
						InputStream in = conn.getInputStream();
						//将返回的流数据解析成图片
						Bitmap bitmap = BitmapFactory.decodeStream(in);
						//使用handler传递消息
						Message msg = Message.obtain();
						msg.obj = bitmap;//传递的数据
						handler.sendMessage(msg);

						in.close();
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}.start();

	}

}

注意两点:

Message对象的创建使用obtain方法可以达到对象重用的目的,节省内存开销。

Message对象可以使用msg.what = 传递消息的类型,handler可以根据传递的消息类型做不同处理,优化代码如下:

package com.ccl.getimage;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
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 SUCCESS = 0;
	protected static final int ERROR = 1;
	protected static final int NETWORK_ERROR = 2;
	private EditText et_path;
	private ImageView iv;
	private String path;

	//使用Handler更新主线程(UI线程)
	private Handler handler = new Handler(){
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SUCCESS:
				Bitmap bitmap = (Bitmap) msg.obj;
				iv.setImageBitmap(bitmap);
				break;
			case ERROR:
				Toast.makeText(MainActivity.this, "获取图片失败", 0).show();
				break;
			case NETWORK_ERROR:
				Toast.makeText(MainActivity.this, "连接网络失败", 0).show();
				break;
			}
		};
	};

	@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 getImage(View view){
		path = et_path.getText().toString().trim();
		if(TextUtils.isEmpty(path)){
			Toast.makeText(this, "地址不能为空", 0).show();
			return;
		}
		new Thread(){
			public void run(){
				try {
					URL url = new URL(path);

					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			        conn.setRequestMethod("GET");
			        conn.setReadTimeout(5000);
					System.out.println("响应码是--"+conn.getResponseCode());
					if(conn.getResponseCode()==200){
						//获取服务器返回的流数据
						InputStream in = conn.getInputStream();
						//将返回的流数据解析成图片
						Bitmap bitmap = BitmapFactory.decodeStream(in);
						//使用handler传递消息
						Message msg = Message.obtain();
						msg.obj = bitmap;//传递的数据
						msg.what = SUCCESS;//传递的消息类型,handler可根据消息类型做不同处理
						handler.sendMessage(msg);
						in.close();
					}else{
						Message msg = Message.obtain();
						msg.what = ERROR;
						handler.sendMessage(msg);
					}

				} catch (Exception e) {
					Message msg = Message.obtain();
					msg.what = NETWORK_ERROR;
					handler.sendMessage(msg);
					e.printStackTrace();
				}
			}

		}.start();

	}

}
时间: 2024-10-13 04:18:17

Android连接网络异常:android.os.NetworkOnMainThreadException的相关文章

android程序连接网络出现android.os.NetworkOnMainThreadEx

android程序连接网络出现android.os.NetworkOnMainThreadEx 错误: android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099) ...... 原因:是涉及到url操作的时候,访问网络不能在主程序中运行 解决:参考[http://geeksun.iteye.com/blog/1447

android 连接网络的简单实例

1.android有两种连接网络的类HttpURLConnect和HttpClient,但是HttpClient已逐渐被HttpURLConnect类代替所以就不提及. 2.实例 String address = "http://www.baidu.com"; URL url = new URL(address);//将String类型转化成URL类型 HttpURLConnect con = (HttpURLConnect)url.openConnection();//创建一个指向要

【Android】常见异常 —— android.view.WindowLeaked 分析以及解决办法

问题虽小,不过不知道还是比较麻烦的.异常信息: 10-22 10:19:38.651 12723-12723/cn.com.zte.uc E/WindowManager﹕ android.view.WindowLeaked: Activity cn.com.zte.uc.activites.shipTicket.OrderWrite1 has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{423fee70

android.os.NetworkOnMainThreadException 在4.0之后谷歌强制要求连接网络不能在主线程进行访问

谷歌在4.0系统以后就禁止在主线程中进行网络访问了,原因是: 主线程是负责UI的响应,如果在主线程进行网络访问,超过5秒的话就会引发强制关闭, 所以这种耗时的操作不能放在主线程里.放在子线程里,而子线程里是不能对主线程的UI进行改变的, 因此就引出了Handler,主线程里定义Handler,子线程里使用. 消息机制的写法 [1] anr Application not response 应用无响应 主线程(UI线程) [2] 如果在主线程中进行了耗时的操作 (比如连接网络 拷贝大的数据) Th

android网络访问异常:android.os.NetworkOnMainThreadException

Caused by: android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java) at java.net.InetAddress.lookupHostByName(InetAddress.java:388) at java.net.InetAddress.getAllByNameImpl(InetAddress.java:23

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="

安卓开发解决android.os.NetworkOnMainThreadException异常方法(主线程不能直接调用webservice)

安卓开发解决android.os.NetworkOnMainThreadException异常方法 2013-01-07 14:01:04|  分类: 技术 |  标签:安卓  技术  java  |举报|字号 订阅 在android 2.3上访问网络的方法,在android 4.0上运行时报android.os.NetworkOnMainThreadException异常,主要问题在于4.0中访问网络不能在主线程中进行,有两个方法可以解决.第一种是在主线程中增加如下代码[不推荐]: // 详见

android之android.os.NetworkOnMainThreadException异常

使用android测试访问web服务器的webservice时,在MainActivity的主线程中访问webservice,代码如下: package com.example.myandroidpro; import java.io.File; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationE

Android Eclipse工程开发中的常见调试问题(二)android.os.NetworkOnMainThreadException 异常的解决办法

android.os.NetworkOnMainThreadException 异常的解决办法, 刚开是把HttpURLConnectionnection 打开连接这个方法放在UI线程里了,可能不是线程安全的,而且这个方法请求是需要等待的,所以就抛出了这个异常,后来用子线程打开的HttpURLConnection, 一切就都正常了,只要在主线程里开启子线程就行了.子线程利用URL 问题解决.下面贴一段代码 String file1 = SERVER_PATH; URL url = new URL