【问题标题】:IllegalStateException in AsyncTask. The content of adapter has changed but listview did not receive a notificationAsyncTask 中的 IllegalStateException。适配器的内容发生了变化但listview没有收到通知
【发布时间】:2013-11-04 07:35:48
【问题描述】:

我正在研究 TCP 套接字。我每 1 秒从服务器接收一次数据,我需要在 ListView 的屏幕上显示它。 为此,我使用了 AsyncTask。

但我经常收到 IllegalStateException 错误

我的代码:

Handler handler = new Handler();
Timer timer = new Timer();

TimerTask doAsynchronousTask = new TimerTask() {

    @Override
    public void run() {
        finalizer = new Runnable() {
            public void run() {
                try {
                    if (navBool) {
                        runOnUiThread(new Runnable() {
                            public void run() {
                                new RetriveStock().execute(); // AsyncTask.
                            }
                        });

                    }
                } catch (Exception e) {
                }
            }
        };
        handler.post(finalizer);
    }
}; 
timer.schedule(doAsynchronousTask, 0, 1000);

// AsyncTask 类

public class RetriveStock extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {
        message = client.clientReceive(1); // Here I receive data from server and stores it in "message" string variable.
        printJson(); // FUNCTION WHICH UPDATE VALUES IN 'obj' OBJECT
       runOnUiThread(new Runnable() {

            @Override
            public void run() {
                updateList();// FUNCTION WHICH UPDATE THE LISTVIEW UI.
                adb.notifyDataSetChanged();
            }
        });

        return null;
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
    }

    @Override
    protected void onPostExecute(Void result) {

                if (adb != null) {
                    lv.invalidateViews();
                    lv.setAdapter(adb);
                    adb.notifyDataSetChanged();
                    lv.requestLayout();

                }


        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
    }

}

// 更新 JSON 值的函数。

    public void printJson() {
    try {
        JSONArray jsonArray = new JSONArray(message);

        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject json = jsonArray.getJSONObject(i);


            String symbol = json.getString("Symbol_En");
            User obj = new User();
            boolean checkSymbol = false;
            for (int j = 0; j < list.size(); j++) {
                obj = list.get(j);
                if (obj.getSymbol().equalsIgnoreCase(symbol)) {
                    checkSymbol = true;
                    break;
                }
            }
            if (!checkSymbol) {
                obj = new User();
                obj.Symbol_En = json.getString("Symbol_En");
                obj.Symbol_Ar = json.getString("Symbol_Ar");
                obj.AskPrice = json.getString("Ask");
                obj.BidPrice = json.getString("Bid");
                obj.AskQuantity = json.getString("AskQuantity");
                obj.High = json.getString("High");
                obj.Low = json.getString("Low");
                obj.Open = json.getString("Open");
                obj.Close = json.getString("Close");
                obj.PerChange = json.getString("PerChange");
                obj.NetChange = json.getString("NetChange");
                obj.Volume = json.getString("Volume");
                obj.Ltp = json.getString("LTP");
                obj.TimeStamp = json.getString("TimeStamp");
                obj.symbolId = json.getString("Id");

                    list.add(obj);
            } else {

                obj.Symbol_En = json.getString("Symbol_En");
                obj.AskPrice = json.getString("Ask");
                obj.BidPrice = json.getString("Bid");
                obj.High = high + "";
                obj.Low = low + "";
                obj.Open = json.getString("Open");
                obj.Close = json.getString("Close");
                obj.PerChange = json.getString("PerChange");
                obj.NetChange = json.getString("NetChange");
                obj.Volume = json.getString("Volume");
                obj.Ltp = json.getString("LTP");
                obj.TimeStamp = json.getString("TimeStamp");
                obj.symbolId = json.getString("Id");

            }

        }
    } catch (JSONException e1) {
        e1.printStackTrace();
    }
}

// 更新 LISTVIEW UI 的函数。

public void updateList() {
        adb = new ArrayAdapter<User>(DefaultMarketWatch.this,
                R.layout.rssitemview, list) {

            @Override
            public View getView(final int position, View convertView,
                    ViewGroup parent) {
                View view = convertView;
                try {
                    if (null == view) {
                        LayoutInflater vi = (LayoutInflater) DefaultMarketWatch.this
                                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        view = vi.inflate(R.layout.rssitemview, null);
                    }
                    final User u = list.get(position);
                    if (null != u) {
                        final TextView title = (TextView) view
                                .findViewById(R.id.symbol);
                        final TextView persend = (TextView) view
                                .findViewById(R.id.persent);
                        final TextView ltp = (TextView) view
                                .findViewById(R.id.ltp);
                        final TextView high = (TextView) view
                                .findViewById(R.id.high);
                        final TextView low = (TextView) view
                                .findViewById(R.id.low);
                        final TextView persendBold = (TextView) view
                                .findViewById(R.id.persent_bold);
                        final TextView persendSup = (TextView) view
                                .findViewById(R.id.persent_sup);

                                ltp.setText(u.getLtp());
                                title.setText(u.getSymbol());
                                high.setText(u.getHigh());
                                low.setText(u.getLow());
                                    persend.setText(u.getPerChange());

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

            }

        };
}

【问题讨论】:

    标签: android listview android-listview android-asynctask illegalstateexception


    【解决方案1】:

    你的日志说

    The content of the adapter is changed but listview did not receive notification. make sure content of your adapter is not modified from background thread but only from ui thread.
    

    你有updateList() // FUNCTION WHICH UPDATE THE LISTVIEW UIin doInBackgrounddoInbackground 在后台线程上调用。您需要在 Ui 线程上更新 ui。

    使用runOnUiThread 这是活动方法或在doInbackground 中返回结果并在onPostExecute 中更新列表视图

    【讨论】:

    • 首先我也做了同样的事情。但返回相同的结果。非法状态异常。现在我用 runOnUiThread 修改了我的 updateList()。请看一看。
    • @user2085965 没有错误尝试将updateList 放入runOnUiThread 并调用 notifyDataSetChanged 以在更新时刷新列表视图
    • @user2085965 其次不要在此处发布快照发布堆栈跟踪。选择异常部分并使用屏幕截图右上角的详细旁边的按钮并在此处发布异常
    • 仍然得到相同的结果。我将 updateList() 放入 runOnUiThread 并在函数内删除。请看我的代码我已经按照你说的更新了。
    • @user2085965 发布堆栈跟踪以获得进一步帮助
    猜你喜欢
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多