2017-08-29 70 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(); 
       } 
}