我最近开发了一个应用程序,它将来自网络服务器的数据连接并解析为Android设备,在froyo和gingerbread上进行测试,工作正常但在ICS设备上崩溃。至于UI,我使用gingebread对象,所以我认为这不是问题。
即使在连接到Facebook之后,它在第一次运行时也能正常工作,但在获取和解析所有收集的JSON数据的部分出现错误。
以下是来自设备的logcat错误:
E/AndroidRuntime(25620): FATAL EXCEPTION: Thread-9660
E/AndroidRuntime(25620): java.lang.UnsupportedOperationException
E/AndroidRuntime(25620): at java.lang.Thread.stop(Thread.java:1076)
E/AndroidRuntime(25620): at java.lang.Thread.stop(Thread.java:1063)
E/AndroidRuntime(25620): at com.android.guestlist.SplashScreen$1.run(Spla
shScreen.java:89)
E/android.os.Debug( 2090): !@Dumpstate > dumpstate -k -t -n -z -d -o /data/log/d
umpstate_app_error
E/Launcher(18546): Error finding setting, default accessibility to not found: ac
cessibility_enabled
E/log_tag (25620): Error in http connection android.os.NetworkOnMainThreadExcept
ion
E/log_tag (25620): Error converting result java.lang.NullPointerException
E/log_tag (25620): Error parsing data org.json.JSONException: End of input at ch
aracter 0 of
E/log_tag (25620): Error in http connection android.os.NetworkOnMainThreadExcept
ion
E/log_tag (25620): Error converting result java.lang.NullPointerException
E/log_tag (25620): Error in http connection android.os.NetworkOnMainThreadExcept
ion
E/log_tag (25620): Error parsing data org.json.JSONException: End of input at ch
aracter 0 of
这是我的JSON解析器,因为我认为这是问题发生的地方?哦,我创建的日志甚至没有出现在手机日志中我真的不能说,但这里是代码:
public void getDataFromWeb(String a, String b){
String result = "";
Log.v(TAG, "Name Value Pair a " + a);
Log.v(TAG, "Name Value Pair b " + b);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("a_param",a));
nameValuePairs.add(new BasicNameValuePair("b_param",b));
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://[mywebserviceshere].php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
Log.v(TAG, "connected");
}catch(Exception e){
Log.v(TAG, "run failed");
Log.e("log_tag", "Error in http connection "+e.toString());
}
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
sb = new StringBuilder();
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
Log.v(TAG, "buffered read");
}catch(Exception e){
Log.v(TAG, "buffered error");
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
Log.v(TAG, result);
JSONArray jArray = new JSONArray(result);
JSONObject json_data=null;
for(int i=0;i<jArray.length();i++){
Log.v(TAG, "loop start");
json_data = jArray.getJSONObject(i);
w.add(json_data.getString("w_data"));
x.add(json_data.getString("x_data"));
y.add(json_data.getString("y_data"));
z.add(json_data.getString("y_data"));
Log.v(TAG, "list added");
}
}catch(JSONException e){
w.add("0");
x.add("No Data");
y.add("No Data");
z.add("No Data");
Log.v(TAG, "rest failed");
Log.e("log_tag", "Error parsing data "+e.toString());
}
}
最后,这正是AVD中的样子:
这是ICS的一个问题,还是我必须修改一些代码?
答案 0 :(得分:4)
您已获得NetworkOnMainThreadException
,这通常是代码不佳的迹象,并且会导致糟糕的用户体验,因为应用程序在运行时会锁定一种网络活动。是的,(不幸的是)它适用于蜂窝前装置,但它不是任何人都应该使用的。
要解决您的问题,我强烈建议您使用单个AsyncTask
并使用doInBackground()
方法执行所有HTTP调用。完成后,将自动调用onPostExecute()
方法,以便您可以更新GUI。很简单。
在执行任何其他操作之前,请先查看AsyncTask
的文档并了解它。我确信这适用于您的应用:http://developer.android.com/reference/android/os/AsyncTask.html
所以不 - 冰淇淋三明治不是问题。它只是不允许你在主线程上发出网络请求,因为它可以阻止其他一切。
(这与我几天前回答的另一个问题很相似,所以答案的一部分是从那里复制的:https://stackoverflow.com/a/11897381/762442)
答案 1 :(得分:1)
您将收到此异常,因为您正在主线程中执行网络操作
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://[mywebserviceshere].php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
在Honeycomb之前允许这样做,但是在蜂巢之后这已经停止了,如果你这样做了,你将获得NetworkOnMainThreadException。
因此最好使用AsyncTask。使用此方法,您可以在后台线程(主线程除外)中执行网络操作。
要详细了解AsyncTask
的工作原理,请参阅此link
答案 2 :(得分:0)
在代码中使用Asynctask获取NetworkOnMainThreadException, 不仅有ics,还有蜂窝,它给你相同的例外。