Состояние гонки в Сервисе (Android) (слишком много тем) - PullRequest
1 голос
/ 13 сентября 2011

Я не знаю почему, но эта функция идет в цикле под таймером, пользователь указывает, как долго он хочет ждать между обновлениями.Каким-то образом функция останавливается (зависает) в части, где "System.out.println (" проверка добавления нового комментария ");".Интересно, что этот код запускается несколько раз, прежде чем все приложение зависает, поэтому в нем нет ошибок

public ArrayList<String> newComments = new ArrayList<String>();
private ArrayList<String> downloadedComments = new ArrayList<String>();

 onStart(){
    if (receivedComments != null) {fthread
                for (int i = 0; i < receivedComments.size(); i++) {
                    if (newComments.contains(receivedComments.get(i))) {
                        System.out.println("Contains.");
                        newComments.remove(receivedComments.get(i));
                    }
                }
            }
    }

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        System.out.println("got msg");
        switch (msg.what) {
        case 1:
            int add = 0;
            System.out.println("start filling the comments");
            for (int i = 1; i < comments.size(); i++) {
                newComment = comments.get(i).text();
                // System.out.println(newComment);
                System.out.println("checking to add a new comment");
                if (!downloadedComments.contains(newComment)) {
                    newComments.add(newComment);
                    System.out.println("additing");
                    downloadedComments.add(newComment);
                    System.out.println("added");
                    add++;
                    // System.out.println("New comments");
                    // System.out.println(newComments);
                }
                // downloadedComments.add(newComment);
            }

            // System.out.println(add);

            break;

        case 2:
            System.out.println("time refresh");
            timeUpdate.scheduleAtFixedRate(new UpdateGui(context,
                    appWidgetManager), 1, 3000);
        }
    }
};

UpdateGUI class

private class UpdateGui extends TimerTask {
        Context context;

        public UpdateGui(Context context, AppWidgetManager appWidgetManager) {
            this.context = context;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (true) {
                for (int i = 0; i < newComments.size(); i++) {
                    try {
                        System.out.println("sleeping");
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    if (newComments.size() > 0) {
                        notificationView.setViewVisibility(
                                R.id.widget_notificationtext,
                                LinearLayout.VISIBLE);
                        notificationView.setTextViewText(
                                R.id.widget_notificationtext,
                                String.valueOf(newComments.size()));
                    } else {
                        notificationView.setViewVisibility(
                                R.id.widget_notificationtext,
                                LinearLayout.INVISIBLE);
                    }
                    if (newComments.size() != 0) {
                        remoteViews.setTextViewText(R.id.widget_text,
                                newComments.get(i));
                    } else {
                        remoteViews.setTextViewText(R.id.widget_text,
                                "No unread comments");
                    }
                    appWidgetManager.updateAppWidget(thisWidget, remoteViews);
                    appWidgetManager.updateAppWidget(thisWidget,
                            notificationView);
                }
try {
                        System.out.println("sleeping");
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
            }
        }

    }

Так как я жду каждый раз 3 секунды, чтобы обновить мой графический интерфейс из потока, я не думал, что делать, когда нет ничего, чтобы обновить его, поэтому код выполняется сразу,но теперь я добавил задержку в три секунды, и все работает отлично.Я знаю, что это не лучший дизайн приложения, но я не мог придумать ничего более эффективного, чем это сейчас.Это было типичное состояние гонки во время обновления, когда обновлять нечего, поэтому простой сон поможет

1 Ответ

0 голосов
/ 13 сентября 2011

Готов поспорить, что это в основном проблема состояния гонки. Вы используете кучу разных потоков (UI, Timer, Handler и, возможно, больше). ArrayList не является синхронизированным или потокобезопасным классом, что означает, что вполне возможно, что downloadedComments обновляется, в то время как одновременно выполняется .contains (), в результате чего внутренний цикл работает в основном навсегда. Если вы не передаете данные различным целям (таким образом, гарантируя, что ничего не изменяется в двух местах), вам придется заключить доступ в блоки synchronized для предотвращения одновременного доступа.

Обратите внимание, что вы можете получить синхронизированную версию списка следующим образом:

List list = Collections.synchronizedList(new ArrayList(...));

Синхронизация каждого метода влияет на производительность. Это, возможно, не имеет значения для вас.

...