这让我发疯了。我被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.
答案 0 :(得分:1)
首先,不要使用线程进行网络请求。
使用AsyncTask或Http库,如Retrofit或volley等库。因为它们提供了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();
}
}