Android 4主线程访问网络 .

本文介绍了解决Android应用中网络访问限制的方法。一种方法是在主线程中解除网络访问限制,但此方法仅适用于API-9及更高版本。另一种方法是通过多线程进行网络访问,避免影响主线程性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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


解决问题的思路有两种:

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

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

<span class="pln" style="color:#000000;"> </span><span class="typ" style="color:#66066;">StrictMode</span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">setThreadPolicy</span><span class="pun" style="color:#66660;">(</span><span class="kwd" style="color:#0088;">new</span><span class="pln" style="color:#000000;"> </span><code style="LINE-HEIGHT: 14px"><a target=_blank style="COLOR: rgb(37,138,175); TEXT-DECORATION: none" href="http://developer.android.com/reference/android/os/StrictMode.ThreadPolicy.Builder.html" target="_blank"><span class="typ" style="color:#66066;">StrictMode</span><span class="pun" style="color:#66660;">.</span><span class="typ" style="color:#66066;">ThreadPolicy</span><span class="pun" style="color:#66660;">.</span><span class="typ" style="color:#66066;">Builder</span></a></code><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">detectDiskReads</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">detectDiskWrites</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">detectNetwork</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">   </span><span class="com" style="color:#8800;">// or .detectAll() for all detectable problems</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">penaltyLog</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">build</span><span class="pun" style="color:#66660;">());</span><span class="pln" style="color:#000000;">
         </span><span class="typ" style="color:#66066;">StrictMode</span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">setVmPolicy</span><span class="pun" style="color:#66660;">(</span><span class="kwd" style="color:#0088;">new</span><span class="pln" style="color:#000000;"> </span><code style="LINE-HEIGHT: 14px"><a target=_blank style="COLOR: rgb(37,138,175); TEXT-DECORATION: none" href="http://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder.html" target="_blank"><span class="typ" style="color:#66066;">StrictMode</span><span class="pun" style="color:#66660;">.</span><span class="typ" style="color:#66066;">VmPolicy</span><span class="pun" style="color:#66660;">.</span><span class="typ" style="color:#66066;">Builder</span></a></code><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">detectLeakedSqlLiteObjects</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">detectLeakedClosableObjects</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">penaltyLog</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">penaltyDeath</span><span class="pun" style="color:#66660;">()</span><span class="pln" style="color:#000000;">
                 </span><span class="pun" style="color:#66660;">.</span><span class="pln" style="color:#000000;">build</span><span class="pun" style="color:#66660;">());</span>

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


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

以下是一段测试代码:

  1. public class MainActivity extends Activity {  
  2.   
  3.     private Button btnTest;  
  4.     private Button btnClear;  
  5.     private TextView txtResult;  
  6.     private Handler handler = null;  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         // StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()   
  11.         // .detectDiskReads()   
  12.         // .detectDiskWrites()   
  13.         // .detectNetwork() // or .detectAll() for all detectable problems   
  14.         // .penaltyLog()   
  15.         // .build());   
  16.         // StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()   
  17.         // .detectLeakedSqlLiteObjects()   
  18.         // .detectLeakedClosableObjects()   
  19.         // .penaltyLog()   
  20.         // .penaltyDeath()   
  21.         // .build());   
  22.   
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.activity_main);  
  25.         btnTest = (Button) findViewById(R.id.btnTest);  
  26.         btnClear = (Button) findViewById(R.id.btnClear);  
  27.         txtResult = (TextView) findViewById(R.id.txtResult);  
  28.         //   
  29.         handler = new Handler() {  
  30.             public void handleMessage(Message msg) {  
  31.                 super.handleMessage(msg);  
  32.                 if (msg.what == 0) {  
  33.                     txtResult.append("\nBegin test >>\n");  
  34.                 } else if (msg.what == 1) {  
  35.                     txtResult.append(msg.obj.toString());  
  36.                 } else if (msg.what == 2) {  
  37.                     txtResult.append("\n<<End test\n");  
  38.                 }  
  39.             }  
  40.         };  
  41.         //   
  42.         txtResult.setText("");  
  43.         txtResult.setMovementMethod(ScrollingMovementMethod.getInstance());  
  44.   
  45.         btnTest.setOnClickListener(new View.OnClickListener() {  
  46.   
  47.             @Override  
  48.             public void onClick(View v) {  
  49.                 // doTest();   
  50.                 doTestOnAndroid4();  
  51.             }  
  52.         });  
  53.         btnClear.setOnClickListener(new View.OnClickListener() {  
  54.   
  55.             @Override  
  56.             public void onClick(View v) {  
  57.                 doClear();  
  58.   
  59.             }  
  60.         });  
  61.   
  62.     }  
  63.   
  64.     protected void doClear() {  
  65.         txtResult.setText("");  
  66.   
  67.     }  
  68.   
  69.     protected void doTest() {  
  70.   
  71.         String url = "http://www.baidu.com/";  
  72.         txtResult.append("\nBegin test >>\n");  
  73.         String text = "";  
  74.         try {  
  75.             text = Jsoup.connect(url).get().toString();  
  76.         } catch (Exception e) {  
  77.             e.printStackTrace();  
  78.             // text = e.getMessage();   
  79.         }  
  80.         txtResult.append(text);  
  81.         txtResult.append("\n<<End test\n");  
  82.     }  
  83.   
  84.     protected void doTestOnAndroid4() {  
  85.   
  86.         new Thread(new Runnable() {  
  87.             @Override  
  88.             public void run() {  
  89.                 Message m = new Message();  
  90.                 m.what = 0;  
  91.                 handler.sendMessage(m);  
  92.                 //   
  93.                 m = new Message();  
  94.                 m.what = 1;  
  95.                 String url = "http://www.baidu.com/";  
  96.                 try {  
  97.                     m.obj = Jsoup.connect(url).get().toString();  
  98.                 } catch (Exception e) {  
  99.                     e.printStackTrace();  
  100.                     // m.obj = e.getMessage();   
  101.                 }  
  102.                 handler.sendMessage(m);  
  103.                 //   
  104.                 m = new Message();  
  105.                 m.what = 2;  
  106.                 handler.sendMessage(m);  
  107.             }  
  108.         }).start();  
  109.   
  110.     }  
  111.   
  112. }  
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();

	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值