本问题已经有最佳答案,请猛点这里访问。
这里我使用此代码加载Json。 它与Android 2.2工作正常,但当我使用Android 4.2它抛出android.os.NetworkOnMainThreadException异常请给我解决方案
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json ="";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet(url);
HttpResponse getResponse = httpClient.execute(httpPost);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(),
"Error" + statusCode +" for URL" + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
//HttpResponse httpResponse = httpClient.execute(httpPost);
//HttpEntity httpEntity = httpResponse.getEntity();
is = getResponseEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
Log.d("IO", e.getMessage().toString());
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is,"iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line +"
");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error","Error converting result" + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser","Error parsing data" + e.toString());
}
// return JSON String
return jObj;
}
}
我也在使用谷歌API。
问题已在这里得到解答:stackoverflow.com/questions/5150637/…
stackoverflow.com/a/12615724/1168654
在setContentView(R.layout.activity_main)之后将下面的代码写入MainActivity文件;
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
并将import语句放到你的java文件中。
import android.os.StrictMode;
这不是关闭StrictMode的正确方法。 正确的方法是在AsyncTask中调用网络操作而不是关闭
正如@SankarV所说,应该使用AsyncTask而不是关闭strictmode。
不建议这样做。 AsyncTask是一种更好的方法。
这是正确的方法:
public class JSONParser extends AsyncTask {
static InputStream is = null;
static JSONObject jObj = null;
static String json ="";
// constructor
public JSONParser() {
}
@Override
protected String doInBackground(String... params) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet(url);
HttpResponse getResponse = httpClient.execute(httpPost);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(),
"Error" + statusCode +" for URL" + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
//HttpResponse httpResponse = httpClient.execute(httpPost);
//HttpEntity httpEntity = httpResponse.getEntity();
is = getResponseEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
Log.d("IO", e.getMessage().toString());
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is,"iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line +"
");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error","Error converting result" + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser","Error parsing data" + e.toString());
}
// return JSON String
return jObj;
}
protected void onPostExecute(String page)
{
//onPostExecute
}
}
要调用它(从main):
mJSONParser = new JSONParser();
mJSONParser.execute();
你甚至测试过吗? 不起作用的是什么网址? return obj在循环外部无法访问
请确保您不在UI线程上进行任何网络访问,而是在异步任务中执行此操作
您的应用程序在Android 3.0及更高版本上崩溃的原因,但在Android 2.x上工作正常是因为HoneyComb对滥用UI线程更加严格。例如,当运行HoneyComb或更高版本的Android设备检测到UI线程上的网络访问时,将抛出NetworkOnMainThreadException。
看到这个
而不是HoneyComb和冰淇淋三明治我会说自HoneyComb。 实际上JB有相同的政策
使用StrictMode这样的东西: -
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
这不是关闭StrictMode的正确方法。 正确的方法是在AsyncTask中调用网络操作而不是关闭。 他们提供的支票只是为了关闭吗?
我们也可以使用asynkTask,但对我来说它的工作原理
你会工作,但不是最好的方式。 他们提供了检查以确保开发人员在单独的线程中调用网络操作而不是简单地关闭。
喔! thanx asyncTask很好
当您尝试访问主线程上的网络时(主活动执行),会发生android.os.NetworkOnMainThreadException。要避免这种情况,您必须创建一个单独的线程或AsyncTask或Runnable实现来执行JSON数据加载。由于HoneyComb,您无法在主线程上进一步执行网络任务。
以下是使用AsyncTask执行网络任务的实现