обновлять положение маркера каждый раз в асинхронной задаче - PullRequest
0 голосов
/ 09 декабря 2018

Я хотел смоделировать местоположение маркера на карте.У меня есть список хранения значений LatLng в ArrayList.Я использую это значение для обновления на карте каждую секунду.Мне нужно, чтобы эта функция работала в AsyncTask, чтобы мой поток пользовательского интерфейса все еще реагировал.

Изначально я пытался использовать Thread.sleep(), но приложение не отвечало.

protected String doInBackground(Void... voids) {
    new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < waypoint.size(); i++) {
                marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
                marker.setPosition(waypoint.get(i));
                try {
                    Thread.sleep(1000); // Thread sleep made application not responsive.
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }, 500);
    return null;
}

Я также пытался использовать.postDelayed но целое число i должно быть объявлено как final, что является проблемой, потому что мне нужно целое число для изменения значения.

protected String doInBackground(Void... voids) {
    for (int i = 0; i < waypoint.size(); i++) {
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
                marker.setPosition(waypoint.get(i)); // Integer i needs to declare final.
            }
        }, 1000);
    }
    return null;
}

Есть ли способ сделать это?Спасибо.

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Самый быстрый (но не самый правильный при работе с MultiThreading) способ:

protected String doInBackground(Void... voids) {
for (final TYPE_OF_WAYPOINT cWaypoint : waypoint) {
    new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
        @Override
        public void run() {
            marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
            marker.setPosition(cWaypoint);
        }
    }, 1000);
}
return null;

}

Я не знаю, что было типом списка "waypoint",поэтому я написал "TYPE_OF_WAYPOINTS" в качестве заполнителя.

0 голосов
/ 14 декабря 2018

@ emandt ответ не работает, но идея, которую он дал, может сработать.Поэтому я попытался, и он работает безупречно с некоторыми изменениями из его ответа:

protected String doInBackground(Void... voids) {
for (final TYPE_OF_WAYPOINT cWaypoint : waypoint) {
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
            marker.setPosition(cWaypoint);
        }
    });
    try {
        Thread.sleep(1000);
    } catch (Exception e) {
        // catch exception here
    }
}
return null;
}

Во-первых, я изменил .postDelayed на .post.Затем, чтобы отложить операцию на одну секунду, я добавил Thread.sleep(1000) внутри for (...), но снаружи new Handler(Looper.getMainLooper()).post(...));.

Теперь приложение может выполнять процесс в фоновом режиме, при этом пользователь все еще может взаимодействоватьс пользовательским интерфейсом.Спасибо.

0 голосов
/ 10 декабря 2018

Подход Thread.sleep() в порядке, если вы можете сэкономить рабочий поток.Проблема в вашем коде в том, что поток, который вы приостанавливаете, является потоком пользовательского интерфейса, поэтому ваше приложение зависает.Вы должны понимать, что в этом случае вы просто публикуете исполняемый файл в потоке пользовательского интерфейса, используя конструкцию Handler, не более того.

Во втором подходе вы можете сбросить часть Handler и использовать publishProgress (называемыйиз фона) после переопределения onProgressUpdate (доставлено в потоке пользовательского интерфейса) в вашем классе на основе AsyncTask.Это делает то же самое, но с меньшим количеством шаблонов.Подробнее смотрите https://developer.android.com/reference/android/os/AsyncTask.

Наконец, чтобы обойти окончательное требование в анонимных классах, вы можете объявить окончательный массив из одного элемента и использовать позицию 0 для чтения / записи значения.Надеюсь, вам не нужно будет делать это слишком часто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...