java - Android 异步任务 ArrayList 操作导致 onDraw 中 IndexOutOfBounds

标签 java android asynchronous

我正在使用异步任务从数据库获取对象并将它们放入 ArrayList 中。我还使用同一个 ArrayList 在屏幕上绘制内容。这是通过 for 循环完成的,该循环遍历数组。似乎当异步任务启动时,它会清除数组列表以用新对象填充它,同时 for 循环有时会运行,这会导致 indexOutOfBounds 异常。

如何防止这种行为?

异步:

    // GET ORDER LISTINGS: LIST ORDERS IN RANGE
    public void listOrders() {
        if (Utility.getCurrentLocation() != null) {
            handler.post(new Runnable() {
                public void run() {
                    new ListOrdersTask().execute((Void) null);
                }
            });
        } else {
            // Cannot Determine Location
            showMessage("Cannot Determine Location.");
        }
    }

    class ListOrdersTask extends AsyncTask<Void, Void, Boolean> {
        private void postData() {
            if (user.loggedIn) {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(
                        "http://cyberkomm.ch/sidney/php/getOrders.php");
                try {
                    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
                            4);
                    nameValuePairs.add(new BasicNameValuePair("LatMin", String
                            .valueOf(user.latitude - seekRange)));
                    nameValuePairs.add(new BasicNameValuePair("LatMax", String
                            .valueOf(user.latitude + seekRange)));
                    nameValuePairs.add(new BasicNameValuePair("LongMin", String
                            .valueOf(user.longitude - seekRange)));
                    nameValuePairs.add(new BasicNameValuePair("LongMax", String
                            .valueOf(user.longitude + seekRange)));
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    HttpResponse response = httpclient.execute(httppost);
                    BufferedReader in = new BufferedReader(
                            new InputStreamReader(response.getEntity()
                                    .getContent()));
                    StringBuffer sb = new StringBuffer("");
                    String line = "";
                    while ((line = in.readLine()) != null) {
                        sb.append(line);
                        break;
                    }
                    in.close();
                    responseString = sb.toString();
                    responseString = responseString.substring(0,
                            responseString.length() - 1);

                    // Handle Response
                    user.orderList.clear();
                    String[] tmp1 = responseString.split("\\|");
                    for (String s : tmp1) {
                        String[] tmp2 = s.split(",");
                        Order tmp3 = new Order();
                        tmp3.orderId = tmp2[0];
                        tmp3.placerName = tmp2[1];
                        tmp3.itemName = tmp2[2];
                        tmp3.payment = tmp2[3];
                        tmp3.locationString = tmp2[4];
                        if (user.orderList.size() < 1) {
                            tmp3.yPos = (int) ((user.orderList.size() * orderHeight) + (barHeight * 1.1f)); //
                            // Shadow of Bar is why 1.1f
                            tmp3.xPos = 0;
                        } else {
                            tmp3.yPos = user.orderList.get(user.orderList
                                    .size() - 1).yPos
                                    + orderHeight
                                    + (orderHeight / 7); // + Gap
                            tmp3.xPos = 0;
                        }

                        tmp3.image = orderImage1;
                        user.orderList.add(tmp3);
                    }
                } catch (Exception e) {
                    Log.e("log_tag", "Error:  " + e.toString());
                }
            } else {
                // Must Login
                showMessage("Must Login");
            }
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            postData();
            return null;
        }
    }

抽奖时:

for (int i = 0; i < user.orderList.size(); ++i) {
                    if (user.orderList.size() > 0) {
                        textSize = scrnWidth / 25;
                        paint.setTextSize(textSize);
                        paint.setAlpha(255);
                        if (user.orderList.size() > 0) {
                            canvas.drawBitmap(user.orderList.get(i).image,
                                    user.orderList.get(i).xPos,
                                    user.orderList.get(i).yPos, paint);
                        }
                        paint.setAlpha(150);
                        if (user.orderList.size() > 0) {
                            canvas.drawText(
                                    user.orderList.get(i).itemName,
                                    user.orderList.get(i).xPos + orderHeight
                                            + (orderHeight / 10),
                                    (user.orderList.get(i).yPos + textSize * 1.85f),
                                    paint);
                        }
                        textSize = scrnWidth / 28;
                        paint.setTextSize(textSize);
                        if (user.orderList.size() > 0) {
                            canvas.drawText(
                                    "@" + user.orderList.get(i).placerName,
                                    user.orderList.get(i).xPos + orderHeight
                                            + (orderHeight / 10),
                                    (user.orderList.get(i).yPos
                                            + (textSize * 1.85f) + (textSize * 1.25f)),
                                    paint);
                        }
                    }
                }

最佳答案

您应该在后台编写一个不同的列表,然后在任务完成时用更新替换旧的列表。在更新 View 和替换列表时同步访问(即完整的绘图循环),这样它们就不会干扰。

关于java - Android 异步任务 ArrayList 操作导致 onDraw 中 IndexOutOfBounds,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26010312/

相关文章:

java - JMeter 与 Java Swing 应用程序

java - 从intellij上的tomcat获取错误404

android - 移动屏幕锁定时广播接收器不会触发

Java Swing : JTextArea filling entire allocated space

java - 尝试在 AsyncTask 中添加通知生成器

android - 使用 adb 将应用程序添加到主屏幕

c# - Asp.net Core 中的 HttpContext 异步安全吗?

javascript - 如何从异步调用返回响应?

javascript - 如何从异步调用返回响应?

java - 创建一个 Java 程序来搜索文件中的特定单词