有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java notifyDataSetChanged不使用线程

使用notifyDataSetChanged方法更新UI时遇到问题。 如果我不使用线程执行此操作,它将工作

下面的类实现了Runnable接口,该接口通过Web API获取数据,并更新我的数据库。 在它更新了数据之后,我想更新我的UI,但它不适用于线程概念

public class ExchangeRateUpdateRunnable implements Runnable {

private ExchangeRateDatabase db;
private CustomAdapter adapter;

public ExchangeRateUpdateRunnable(ExchangeRateDatabase db, CustomAdapter adapter) { this.db = db; this.adapter = adapter;}

@Override
public void run() {
    refresh();
}

private void refresh() {
    List<ExchangeRate> exchangeRates = new ArrayList<>();
    String urlString = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
    try {

        URL url = new URL(urlString);
        URLConnection connection = url.openConnection();
        InputStream inputStream = connection.getInputStream();
        String encoding = connection.getContentEncoding();

        XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
        parser.setInput(inputStream, encoding);

        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG) {
                if ("Cube".equals(parser.getName())) {
                    if(parser.getAttributeValue(null,"currency") != null) {
                        String currency = parser.getAttributeValue(null , "currency");
                        String rate = parser.getAttributeValue(null, "rate");
                        ExchangeRate exchangeRate = new ExchangeRate(currency, new Double(rate));
                        exchangeRates.add(exchangeRate);
                    }
                }
            }
            eventType = parser.next();
        }
        inputStream.close();
        updateDB(exchangeRates);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void updateDB ( List<ExchangeRate> exchangeRates) {
    db.setExchangeRate(exchangeRates);
    adapter.notifyDataSetChanged();
}

}

这是一个在mainActivity类上实现的方法,它监听菜单项(这意味着只要我点击该项,它就会调用这个函数)。它实现在后台运行的线程并更新我的数据:

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case R.id.settings:
            Intent intent = new Intent(this, CurrencyListActivity.class);
            startActivity(intent);
        case R.id.refresh:
            new Thread(new ExchangeRateUpdateRunnable(db,adapter)).start();
           //new RefreshRates(db,adapter).refresh(); //single Threaded
    }

    return super.onOptionsItemSelected(item);
}

如果我把代码行:适配器。notifyDataSetChanged();在mainActivity类的方法上,只有单击按钮两次,它才会起作用。但我想在单击按钮后立即更新我的UI

我如何解决这个问题? 这是一个线程问题还是Android无法通过线程处理的问题

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    您将无法从线程中通知数据集更改,您可能需要使用处理程序。post或RUNNUITHREAD可实现此目的

    范例

    try {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.e("updating...", "");
                                Notifydatasetchanged()
                            }
                        });
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }