如上所述,我得到上述错误,我知道是因为我的应用程序正在UI线程中进行联网。我经历了很多stackoverflow问题,建议使用AsyncTask来达到这个目的。据我所知,asynctask是异步的,将在后台独立运行。但我需要从http获取数据并显示在主线程上。所以基本上我的UI线程应该被阻塞,直到我获取了JSON,以便我可以显示它。
我的问题是 1)因为我需要在另一个线程中运行http网络,我该怎么办? 2)我是否使用异步线程? 3)如何阻止异步线程的UI线程获取结果? 4)如何将异步线程的结果传递回UI线程?
这是我使用的当前JSON解析器类。
公共类JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONArray getJSONfromURL(String url) {
// initialize
InputStream is = null;
String result = "";
JSONArray jArray = null;
// http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpclient.execute(httpGet);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
return null;
}
// convert response to string
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 + "\n");
}
is.close();
result = sb.toString();
Log.e("log_tag", "JSON data" + result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
return null;
}
// try parse the string to a JSON object
try {
jArray = new JSONArray(result);
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
return null;
}
return jArray;
}
}
这是我的MainActivity,我调用JSONparser来获取我需要显示的一些数据
JSONArray json = jParser.getJSONfromURL(temp);
if (json == null) {
return -1;
}
for (int i = 0; i < json.length(); i++) {
try {
JSONObject c = json.getJSONObject(i);
// Getting Array of Contacts
// Storing each json item in variable
asr_iq = c.getString("lMAsr");
sunrise_iq = c.getString("lMSunrise");
fajr_iq = c.getString("lMFajr");
isha_iq = c.getString("lMIsha");
dhuhr_iq = c.getString("lMDhuhr");
maghrib_iq = c.getString("lMMaghrib");
} catch (JSONException e) {
e.printStackTrace();
}
}
答案 0 :(得分:1)
在UI线程上加载asynctask。
如果您无法在UI Thread Honeycomb及更高版本上执行任何与网络相关的操作。您将获得NetworkOnMainThread异常。
new MyTask(url).execute();// can pass parameter to class constructor
// can also pass url to doInBackground.
异步任务
class MyTask extends AsyncTask<Void,Void,Void>
{
String url;
public MyTask(String url)
{
this.url =url
}
@Override
protected Void doInBackground(Void... params) {
// all your network related operation
// invoked on the background thread
// all code from getJSONfromURL(param)
// do not update ui here
return null;
}
@Override
protected void onPostExecute(Void result) { // invoked on the ui thread
// TODO Auto-generated method stub
super.onPostExecute(result);
// dismiss progress dialog
// update ui here
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// display progress dialog
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
}
详细信息@ http://developer.android.com/reference/android/os/AsyncTask.html
编辑:
使用处理程序。在doInBaCkground()中返回结果。
onPostExecute()
中的示例 Message msg=new Message();
msg.obj=result.getProperty(0).toString();
mHandler.sendMessage(msg);
在你的活动onCreate()
Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
//ArrayList s=(ArrayList)msg.obj;
SoapObject s =(SoapObject) msg.obj;
tv.setText("Result = "+s.toString());
}
};
您还可以使用runonuithread从doInBackGround()
更新ui runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
_tv.setText("update from doinbackground");
}
});
答案 1 :(得分:0)
使用Core Java,
将您的getJson执行逻辑放在Runnable / Callable(Java并发类)中,通过执行程序提交它,以便进行Asynch调用。
然后在你的Runnable / Callable中,一旦json被重新调用,就会调用具有显示json的逻辑的类,这个clas可以被设计为一个监听器,你可以在获得json响应后发布一个偶数