Android 4主线程访问网络

最近做一个Android项目,利用Jsoup读取和解析网页数据,同样的程序在Android2.3上运行完全正常,而跑到Android4上面,bug出现了...

看了一下异常:android.os.NetworkOnMainThreadException

然后,上网搜索一下才发现,原来Android4默认情况下是不允许在主线程中访问网络的。


解决问题的思路有两种:

1、解除主线程网络访问限制,参见http://developer.android.com/reference/android/os/StrictMode.html

在onCreate中加入以下代码即可:

 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .detectDiskWrites()
                 .detectNetwork()   // or .detectAll() for all detectable problems
                 .penaltyLog()
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());

不过如果要求至少是API-9才可以,否则会编译器提示错误,所以在适配一些低版本系统时候不太给力。


2、多线程中访问网络-既然系统默认不允许在主线程中访问,那么再开一个线程好了,这样在处理复杂流程的时候也不会影响界面的流畅,用户体验也好。

以下是一段测试代码:

public class MainActivity extends Activity {

	private Button btnTest;
	private Button btnClear;
	private TextView txtResult;
	private Handler handler = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
		// .detectDiskReads()
		// .detectDiskWrites()
		// .detectNetwork() // or .detectAll() for all detectable problems
		// .penaltyLog()
		// .build());
		// StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
		// .detectLeakedSqlLiteObjects()
		// .detectLeakedClosableObjects()
		// .penaltyLog()
		// .penaltyDeath()
		// .build());

		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		btnTest = (Button) findViewById(R.id.btnTest);
		btnClear = (Button) findViewById(R.id.btnClear);
		txtResult = (TextView) findViewById(R.id.txtResult);
		//
		handler = new Handler() {
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				if (msg.what == 0) {
					txtResult.append("\nBegin test >>\n");
				} else if (msg.what == 1) {
					txtResult.append(msg.obj.toString());
				} else if (msg.what == 2) {
					txtResult.append("\n<<End test\n");
				}
			}
		};
		//
		txtResult.setText("");
		txtResult.setMovementMethod(ScrollingMovementMethod.getInstance());

		btnTest.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// doTest();
				doTestOnAndroid4();
			}
		});
		btnClear.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				doClear();

			}
		});

	}

	protected void doClear() {
		txtResult.setText("");

	}

	protected void doTest() {

		String url = "http://www.baidu.com/";
		txtResult.append("\nBegin test >>\n");
		String text = "";
		try {
			text = Jsoup.connect(url).get().toString();
		} catch (Exception e) {
			e.printStackTrace();
			// text = e.getMessage();
		}
		txtResult.append(text);
		txtResult.append("\n<<End test\n");
	}

	protected void doTestOnAndroid4() {

		new Thread(new Runnable() {
			@Override
			public void run() {
				Message m = new Message();
				m.what = 0;
				handler.sendMessage(m);
				//
				m = new Message();
				m.what = 1;
				String url = "http://www.baidu.com/";
				try {
					m.obj = Jsoup.connect(url).get().toString();
				} catch (Exception e) {
					e.printStackTrace();
					// m.obj = e.getMessage();
				}
				handler.sendMessage(m);
				//
				m = new Message();
				m.what = 2;
				handler.sendMessage(m);
			}
		}).start();

	}

}






你可能感兴趣的:(java,线程,android,网络)