2017-08-29 72 views
-2

這讓我瘋狂。我被android強制創建一個線程,以便它不鎖定主線程。現在我想將這些數據返回到我創建的ListView適配器。我GOOGLE了錯誤,但不清楚如何修改此代碼。感謝任何幫助,您可以給將HttpURLConnection數據返回到列表視圖適配器

public class Detail extends AppCompatActivity 
{ 
ListView list; 
ListViewAdapter listviewadapter; 
List<CData> lstData = new ArrayList<CData>(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.listview_main); 
    list = (ListView) findViewById(R.id.listview); 
    listviewadapter = new ListViewAdapter(this, R.layout.listview_item, lstData); 
    list.setAdapter(listviewadapter); 

    // these work 
    CData d1 = new CData("test1", "data1", "a"); 
    lstData.add(d1); 

    CData d2 = new CData("test2", "data2", "a"); 
    lstData.add(d2); 

    Thread thread = new Thread(new Runnable(){ 
     @Override 
     public void run(){ 
      try { 
       URL url = new URL("http://testserver.com/getdata.php"); 
       HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
       connection.setRequestMethod("GET"); 
       connection.connect(); 
       InputStream inStream = null; 
       inStream = connection.getInputStream(); 
       BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream)); 
       String temp, response = ""; 
       while ((temp = bReader.readLine()) != null) { 
        response += temp; 
       } 

       // this is not working 
       CData d4 = new CData("test3", response, "a"); 
       lstData.add(d4); 
       listviewadapter.notifyDataSetChanged(); 

       // this prints out to the log window 
       System.out.println("---------------yesss--------" + response); 

       // this does not work 
       listviewadapter.notifyDataSetChanged(); 

       // this does not work either 
       listviewadapter.clear(); 
       listviewadapter.addAll(lstData); 
       listviewadapter.notifyDataSetChanged(); 

      } 

      catch(Exception ex) 
      { 
       System.out.println("generic ex" + ex.toString()); 
      } 
     } 
    }); 
    thread.start(); 


    CData d3 = new CData("test4", "data4", "a"); 
    lstData.add(d3); 

錯誤

CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
+0

更好地利用'asynchtask' –

+0

準確,使用的AsyncTask。在OnStart活動事件中調用您的任務。 –

回答

0

你應該更新UI線程UI這樣

runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 

//stuff that updates ui 

      listviewadapter.clear(); 
      listviewadapter.addAll(lstData); 
      listviewadapter.notifyDataSetChanged(); 

    } 
}); 
+0

你好,這是不是已經在上面的代碼行23上發生?我在另一個s.o上看到了這個例子。但不知道它如何適用於此代碼 – flashc5

+0

U可以把這個代碼裏面運行方法 –

+0

線程只是創建後臺線程,你不能在後臺線程更新ui –

1

首先,不使用線程的網絡請求。

可以使用AsyncTask或Http庫如Retrofitvolley等庫。因爲它們提供了Http Web請求和處理機制的連擊器實現。

從你的代碼這可能是解決方案

runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 

     //UI updates 
     // this does not work either 
     listviewadapter.clear(); 
     listviewadapter.addAll(lstData); 
     listviewadapter.notifyDataSetChanged(); 

    } 
}); 
0

讓您D4可變全球。 您的catch語句後: -

runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        lstData.add(d4); 
        listviewadapter.clear(); 
        listviewadapter.addAll(lstData); 
        listviewadapter.notifyDataSetChanged(); 
       } 
}