应用程序需要获取JSON并显示它。如何使用异步线程?

时间:2013-04-30 21:57:16

标签: android json multithreading android-asynctask

如上所述,我得到上述错误,我知道是因为我的应用程序正在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();
        }
    }

2 个答案:

答案 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,

  1. 将您的getJson执行逻辑放在Runnable / Callable(Java并发类)中,通过执行程序提交它,以便进行Asynch调用。

  2. 然后在你的Runnable / Callable中,一旦json被重新调用,就会调用具有显示json的逻辑的类,这个clas可以被设计为一个监听器,你可以在获得json响应后发布一个偶数