0

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

2 回答 2

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");

                 }
                 });
于 2013-04-30T22:05:49.507 回答
0

使用核心 Java,

  1. 将您的 getJson 执行逻辑放在 Runnable/Callable(Java 并发类)中,通过执行程序提交它,使其成为异步调用。

  2. 然后在您的 Runnable/Callable 中,一旦 json 被检索,调用将具有显示 json 的逻辑的类,这个 clas 可以设计为一个侦听器,您甚至可以在获得 json 响应后发布一个

于 2013-04-30T22:21:06.257 回答