关于处理Android 异常NetworkOnMainThreadException解决方案

  • Post author:
  • Post category:其他


今天帮学弟看一个Demo,出现了

NetworkOnMainThreadException,解决方案如下


首先bug重现

然后我通过logcat日志以及debug模式调试发现sb.toString();全部有值

拿到值

所以不是逻辑的问题于是我去查找资料自己犯了低级错误!

主要提供两种解决方案

方案一

加载setContentView()下面

Android SDK 2.0中访问网络不会出现android.os.NetworkOnMainThreadException异常错误,但在 4.0之后运行则会报此错误(即在主线程访问网络时发生异常)。



原因就是Android在4.0之前的版本都支持在主线程中访问网络,但在4.0以后对这部分程序进行了优化,若在主线程里执行Http请求都会报错,



其原则就是:

UI线程不能有任何的网络访问操作



从 Android 2.3(API9) 开始提供了一个新的类 StrictMode,该类可以用于捕捉发生在应用程序主线程中耗时的磁盘、网络访问或函数调用,可以帮助开发者改进程序,


使主线程处理 UI 和动画在磁盘读写和网络操作时变得更平滑,避免主线程被阻塞。

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

第二种解决方案

就是多线程访问,因此可以采用

AsyncTask

任务方式也是相通的。

这里我就不举例了!get请求
post请求
LogCat
具体代码补充

客户端

package com.weixin;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;


import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;


import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


public class HttpRActivity extends Activity implements OnClickListener {
private TextView tv_name, tv_age;
private EditText et_name, et_age;
private Button btn_get, btn_post;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_httpr);
                 //判断主线程当前的sdk是否大于2.3否则出现NetworkonMainThreadException异常
if (android.os.Build.VERSION.SDK_INT > 9) {
   StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
   StrictMode.setThreadPolicy(policy);
}
initView();
initListener();

}


private void initListener() {
// 设置按钮的监听事件
btn_get.setOnClickListener(this);
btn_post.setOnClickListener(this);


}

private String readString(InputStream in) throws IOException {
byte[] data = new byte[1024];
int length = 0;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
while ((length = in.read(data)) != -1) {
bout.write(data, 0, length);
}
return new String(bout.toByteArray(), "UTF-8");
}


private void initView() {
// 初始化View
tv_age = (TextView) findViewById(R.id.tv_age);
tv_name = (TextView) findViewById(R.id.tv_name);
et_name = (EditText) findViewById(R.id.et_username);
et_age = (EditText) findViewById(R.id.et_age);
btn_get = (Button) findViewById(R.id.btn_get);
btn_post = (Button) findViewById(R.id.btn_post);
}

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_get:
try {
DefaultHttpClient client = new DefaultHttpClient();
StringBuilder buf = new StringBuilder(
"http://192.168.137.184:8080/HouseInfo/HttpsServlet");
buf.append("?");
buf.append("name="
+ URLEncoder.encode(et_name.getText().toString(),
"UTF-8") + "&");
buf.append("age="
+ URLEncoder.encode(et_age.getText().toString(),
"UTF-8"));
HttpGet get = new HttpGet(buf.toString());
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
InputStream in = response.getEntity().getContent();
String str = readString(in);
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
Log.i("get", str.toString());
Log.i("buf:", buf.toString());
} else
Toast.makeText(this, "GET提交失败", Toast.LENGTH_SHORT).show();


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case R.id.btn_post:
try {
DefaultHttpClient client = new DefaultHttpClient();
List<NameValuePair> list = new ArrayList<NameValuePair>();
NameValuePair pairname = new BasicNameValuePair("name", et_name
.getText().toString());
NameValuePair pairage = new BasicNameValuePair("age", et_age
.getText().toString());
list.add(pairname);
list.add(pairage);
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,
"UTF-8");
HttpPost post = new HttpPost(
"http://192.168.137.184:8080/HouseInfo/HttpsServlet");
post.setEntity(entity);
HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() == 200) {
InputStream in = response.getEntity().getContent();// 接收服务器的数据,并                                             在Toast上显示
String str = readString(in);
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
Log.i("post", str.toString());


} else {
Toast.makeText(this, "POST提交失败", Toast.LENGTH_SHORT).show();
}


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();


}
default:
break;
}


}
}


服务端HttpsServlet
package com.hI.controller;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HttpsServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/                       //设置比编码格式网页显示内容text/html
response.setContentType("text/html;charset=utf-8");
                 //获取请求name和age 并转码UTF-8
String name = new String(request.getParameter("name").getBytes(
"ISO-8859-1"), "UTF-8");
String age = new String(request.getParameter("age").getBytes(
"ISO-8859-1"), "UTF-8");
                //响应客户端get请求方式并输出姓名和年龄
System.out.println("GET");
System.out.println("name=" + name);
System.out.println("age=" + age);
response.setCharacterEncoding("UTF-8");
OutputStream out = response.getOutputStream();// 返回数据
out.write("GET请求成功!".getBytes("UTF-8"));
out.close();
// doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
                 //设置编码格式
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
                //获取客户端的请求参数name和age查询字符串拼接
String name = request.getParameter("name");
String age = request.getParameter("age");
               //响应客户端get请求方式并输出姓名和年龄
System.out.println("POST");
System.out.println("name=" + name);
System.out.println("age=" + age);
response.setCharacterEncoding("UTF-8");
OutputStream out = response.getOutputStream();
out.write("POST请求成功!".getBytes("UTF-8"));
out.close();
// doGet(request, response);
}
}




版权声明:本文为qq_15950325原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。