【问题标题】:How to solve issue with mainthread如何解决主线程的问题
【发布时间】:2014-02-15 19:51:55
【问题描述】:

我尝试从 php 文件中获取 JSON 数据

public void connect(){
    System.out.println("%%%%%%%%%%%%%%%%%1" );
    Thread t = new Thread(){

        @Override
        public void run() {

    try {

        System.out.println("%%%%%%%%%%%%%%%%%2" );
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setSoTimeout(params, 0);
        HttpClient httpClient = new DefaultHttpClient(params);
        String urlString = "http://url";
        //prepare the HTTP GET call 
        HttpGet httpget = new HttpGet(urlString);
        //get the response entity
        HttpEntity entity = httpClient.execute(httpget).getEntity();
        System.out.println("%%%%%%%%%%%%%%%%%3" );
        if (entity != null) {
            //get the response content as a string
            String response = EntityUtils.toString(entity);
            //consume the entity
            entity.consumeContent();

            // When HttpClient instance is no longer needed, shut down the connection manager to ensure immediate deallocation of all system resources
            httpClient.getConnectionManager().shutdown();

            //return the JSON response

            JSONArray jsonarray = new JSONArray(response); 
            JSONObject jb =(JSONObject) jsonarray.getJSONObject(0);
            String name= jb.getString("name");
            String punkt = jb.getString("punktezahl");

             //String name = jsonarray.getString("name");
             System.out.println("HEEEEEEEEEEEEEEEEEEEEEEEEEEEE" + name);
             fuehrender.setText(name);
             punkte.setText(punkt);
               }



    }catch (Exception e) {
        e.printStackTrace();
    }
}

};
t.start();
}

如果我这样做,我会收到一条消息,即只有创建视图层次结构的原始线程才能接触其视图。

因此,由于此错误消息,我这样尝试:

public void connect(){
    System.out.println("%%%%%%%%%%%%%%%%%1" );
    runOnUiThread(new Runnable() {

        @Override
        public void run() {

    try {

        System.out.println("%%%%%%%%%%%%%%%%%2" );
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setSoTimeout(params, 0);
        HttpClient httpClient = new DefaultHttpClient(params);
        String urlString = "http://url";
        //prepare the HTTP GET call 
        HttpGet httpget = new HttpGet(urlString);
        //get the response entity
        HttpEntity entity = httpClient.execute(httpget).getEntity();
        System.out.println("%%%%%%%%%%%%%%%%%3" );
        if (entity != null) {
            //get the response content as a string
            String response = EntityUtils.toString(entity);
            //consume the entity
            entity.consumeContent();

            // When HttpClient instance is no longer needed, shut down the connection manager to ensure immediate deallocation of all system resources
            httpClient.getConnectionManager().shutdown();

            //return the JSON response

            JSONArray jsonarray = new JSONArray(response); 
            JSONObject jb =(JSONObject) jsonarray.getJSONObject(0);
            String name= jb.getString("name");
            String punkt = jb.getString("punktezahl");

             //String name = jsonarray.getString("name");
             System.out.println("HEEEEEEEEEEEEEEEEEEEEEEEEEEEE" + name);
             fuehrender.setText(name);
             punkte.setText(punkt);
               }



    }catch (Exception e) {
        e.printStackTrace();
    }
}

});

}
}

现在,我收到了NetworkOnMainThread 错误消息。如何突破这个厄运循环?

【问题讨论】:

  • 将 try-catch 块放在 AsyncTask 中。
  • 简短的回答是:你不能在同一个线程上做网络 ui。

标签: android json multithreading network-connection


【解决方案1】:

您有一个runOnUiThread。去掉它。它应该只用于更新 ui 而不是用于 http get 请求。

使用AsyncTask 是更好的选择。在doInBackground 中发出http get 请求并解析响应。您可以在doInbackground 中返回结果,这是onPostExecute 的参数。

所以你可以更新onPostExecute中的ui,它是在ui线程上调用的。

http://developer.android.com/reference/android/os/AsyncTask.html

例子:

调用

new TheTask().execute(); // in ui thread

使AsyncTask 成为活动的内部类

class TheTask extends AsyncTask<Void,Void,String>
{

    @Override
    protected String doInBackground(Void... params1) {
        String response = null; 
            try {
                HttpParams params = new BasicHttpParams();
                HttpConnectionParams.setSoTimeout(params, 0);
                HttpClient httpClient = new DefaultHttpClient(params);
                String urlString = "http://url";
                HttpGet httpget = new HttpGet(urlString);
                HttpEntity entity = httpClient.execute(httpget).getEntity();
                response = EntityUtils.toString(entity);
                httpClient.getConnectionManager().shutdown();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
         JSONArray jsonarray = new JSONArray(result; 
         JSONObject jb =(JSONObject) jsonarray.getJSONObject(0);
         String name= jb.getString("name");
         String punkt = jb.getString("punktezahl");
         fuehrender.setText(name);
         punkte.setText(punkt);
    }

}

【讨论】:

  • @user896692 你需要使用线程或异步任务。 AsyncTask 更简单。
  • 可能是因为您从UI 调用connect()。从后台调用它Thread。但我同意,AsyncTask 更容易
  • 谢谢,这很有帮助!但是如何从 onPostExecute 访问我的 TextView?
  • @user896692 将 textview 声明为实例变量并在 onCreate 中对其进行初始化。使 AsyncTask 成为 Activity 的内部类。
  • 如果你的 AsyncTask 是一个内部类,你可以在你的 onPostExecute() 方法中引用 TextView。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 2010-11-01
  • 2021-12-26
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多