将HttpURLConnection数据返回到List View Adapter

时间:2017-08-29 17:38:52

标签: java android multithreading

这让我发疯了。我被android强制创建一个线程,以便它不会锁定主线程。现在我想将数据恢复到我创建的ListView适配器。我搜索了错误,但不清楚如何调整此代码。感谢您提供的任何帮助

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.

3 个答案:

答案 0 :(得分:1)

首先,不要使用线程进行网络请求。

使用AsyncTask或Http库,如Retrofitvolley等库。因为它们提供了Http web请求和处理机制的batter实现。

从您的代码中,这可以是解决方案

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

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

    }
});

答案 1 :(得分:0)

您应该像这样更新UI线程上的UI

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

//stuff that updates ui

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

    }
});

答案 2 :(得分:0)

让你的d4变量全局化。 在你的捕获声明之后: -

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