【问题标题】:android.view.viewrootimpl$calledfromwrongthreadexception android javaandroid.view.viewrootimpl$calledfromwrongthreadexception android java
【发布时间】:2014-11-28 06:30:26
【问题描述】:

我已经声明了一个接口:

public interface GetChildList{
        public void onGetChildList(List<String> list);
}

在我的课堂上(我称之为fetchJSONChild())实现:

import com.example.hakslogin.GetChildList;

public class ChildActivity extends ActionBarActivity implements GetChildList {

    Button btn_home;
    Button btn_add;
    private HandleJSON obj;
    public String urlString = "http://192.168.x.xx:xxxx/getdb";

    List<String> child = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);


        obj = new HandleJSON(urlString);
        child = obj.fetchJSONChild(this);
    }

    @Override
    public void onGetChildList(List<String> list) {
       //this method will be called after thread in fetchJSONChild ended
       child = list;
       //here you can work with your list

    }
}

下面是我的fetchJSONChild

public void fetchJSONChild(final GetChildList callBack){

        final List<String> child = new ArrayList<String>();
        Thread thread = new Thread(new Runnable(){

            @Override
            public void run() {

                try {

                    URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setReadTimeout(30000 /* milliseconds */);
                    conn.setConnectTimeout(50000 /* milliseconds */);
                    conn.setRequestMethod("GET");
                    //conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
                    conn.setRequestProperty("Content-Type", "application/json");
                    conn.setDoInput(true);
                    //conn.setUseCaches (false);
                    // Starts the query
                    if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {

                        conn.setRequestProperty("Connection", "close"); 
                    }
                    conn.connect();

                    System.out.println("Before url.openStream()");
                    InputStream stream = conn.getInputStream();//.openStream();
                    System.out.println("After url.openStream()");
                    String data = convertStreamToString(stream);
                    // for examole data = "1,2,3";

                    child.addAll(Arrays.asList(data.split(","));
                    readAndParseJSON(data);
                    stream.close();

                    callBack.onGetChildList(child);
                } catch (Exception e) {

                    e.printStackTrace();
                }
            }
        });
        thread.start(); 
    }

一切正常,我在ChildActivityonGetChildList 方法中获得列表。

但我想在listview 中填充list,如下所示:

@Override
public void onGetChildList(List<String> list) {
   //this method will be called after thread in fetchJSONChild ended
    List<String> array = new ArrayList<String>();
   child = list;
   //onCreate(new Bundle()); 
   lv_child = (ListView)findViewById(R.id.lv_child); 
   String arr[]=child.toArray(new String[list.size()]);
   String[] Temp= new String[2];
          Temp[0] = arr[2].toString();
          array.add(Temp[0].split(":")[1]);
          String s = Temp[0].toString();
   ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,array);
   lv_child.setAdapter(adapter);
   //here you can work with your list
}

但是我遇到了异常android.view.viewrootimpl$calledfromwrongthreadexception

请给我建议,等待回复。

谢谢

【问题讨论】:

    标签: java android list listview


    【解决方案1】:

    尝试使用 AsyncTask 代替 Thread 从服务器获取数据:

       public void fetchJSONChild(final GetChildList callBack){
    
            new AsyncTask<Void,Void,List<String>>(){
                @Override
                protected List<String> doInBackground(Void... params) {
                    List<String> child = new ArrayList<String>();
                    try {
                        URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        conn.setReadTimeout(30000 /* milliseconds */);
                        conn.setConnectTimeout(50000 /* milliseconds */);
                        conn.setRequestMethod("GET");
                        //conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
                        conn.setRequestProperty("Content-Type", "application/json");
                        conn.setDoInput(true);
                        //conn.setUseCaches (false);
                        // Starts the query
                        if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
    
                            conn.setRequestProperty("Connection", "close");
                        }
                        conn.connect();
    
                        System.out.println("Before url.openStream()");
                        InputStream stream = conn.getInputStream();//.openStream();
                        System.out.println("After url.openStream()");
                        String data = convertStreamToString(stream);
                        // for examole data = "1,2,3";
    
                        child.addAll(Arrays.asList(data.split(",")));
                        readAndParseJSON(data);
                        stream.close();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    return child;
                }
    
                @Override
                protected void onPostExecute(List<String> child) {
                    super.onPostExecute(child);
                    callBack.onGetChildList(child);
                }
            }.execute();
    
        }
    

    【讨论】:

      【解决方案2】:

      问题是您正试图从新的Thread 调用onGetChildList(List&lt;String&gt; list) 方法。您不能这样做,因为所有需要在 UI 上完成的工作都必须从主线程(有时称为 UI 线程)执行。你可以阅读更多关于它的信息here
      我建议你在这里创建新的AsyncTask 并将所有代码移到run 方法中,除了最后一行到它的doInBackground() 方法。最后一行需要移到AsyncTask#onPostExecute方法里面,所以整个结构是这样的:

          new AsyncTask<Void,Void,List<String>>(){
              @Override
              protected List<String> doInBackground(Void... params) {
                  List<String> child = new ArrayList<String>();
                  try {
                      // code omitted for brevity
                  }catch (Exception e){
                      e.printStackTrace();
                  }
                  return child;
              }
      
              @Override
              protected void onPostExecute(List<String> child) {
                  super.onPostExecute(child);
                  callBack.onGetChildList(child);
              }
          }.execute();
      

      它将起作用,因为doInBackground() 方法在后台线程内执行,当此方法完成时,AsyncTask 将其结果传递给正在 UI 线程上执行的onPostExecuteAsyncTask 专为此类任务而设计 - 在后台执行某些操作,然后使用结果更新 UI。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        • 2012-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多