Отмените Runnable в методе .runOnFirstFix () объекта LocationOverlay - PullRequest
1 голос
/ 12 июля 2011

У меня есть приложение, которое сильно зависит от функциональности карты.Из первой операции я вызываю метод runOnFirstFix() для загрузки большого количества данных из базы данных, как только местоположение пользователя было найдено, но я также хочу иметь возможность прерывать этот работающий объект и останавливать его в середине выполнения, когда я переключаюсьили пользователь нажимает кнопку, чтобы остановить его выполнение.

myLocationOverlay.runOnFirstFix(new Runnable() {
            public void run() {
                mc.animateTo(myLocationOverlay.getMyLocation());
                mc.setZoom(15);
                userLatitude = myLocationOverlay.getMyLocation().getLatitudeE6();
                userLongitude = myLocationOverlay.getMyLocation().getLongitudeE6();
                userLocationAcquired = true;
                loadMapData();  //Here the method is called for heavy data retrieval    
            }
        });

Как я могу остановить выполнение Runnable в середине?

Ответы [ 3 ]

2 голосов
/ 13 июля 2011

Вы можете (и, вероятно, должны) использовать AsyncTask

private class MapLoader extends AsyncTask<Void, Void, Data> {
    @Override
    protected Data doInBackground(Void... params) {
        return loadMapData();  //Here the method is called for heavy data retrieval, make it return that Data  
    }
    @Override
    protected void onPostExecute(Data result) {
    //do things with your mapview using the loaded Data (this is executed by the uithread)
    }
}

и затем замените ваш другой код на

final MapLoader mapLoader = new MapLoader();
myLocationOverlay.runOnFirstFix(new Runnable() {
    public void run() {
        mc.animateTo(myLocationOverlay.getMyLocation());
        mc.setZoom(15);
        userLatitude = myLocationOverlay.getMyLocation().getLatitudeE6();
        userLongitude = myLocationOverlay.getMyLocation().getLongitudeE6();
        userLocationAcquired = true;
        mapLoader.execute();
    }
});

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

mapLoader.cancel(true);

Надеюсь, код скомпилирован, я его не тестировал, но он должен работать:)

Просто убедитесь, что это поток пользовательского интерфейса, который создает MapLoader

edit: я думаю, что вам нужно обернуть вызов mapLoader.execute(); в вызов runOnUiThread(), чтобы он работал правильно, поскольку runOnFirstFix() может породить новый поток

1 голос
/ 12 июля 2011

используйте объект-обработчик для обработки этого работоспособного объекта.

определите этот работоспособный объект с помощью запускаемого объекта.

после этого в обработчике вы можете запустить отмену этой работающей службы

например,

Handler handler = new Handler();

при startCommand ()

handler.postDelayed(myRunnable,5000);

, при этом метод запуска будет выполнен через 5 секунд

для отмены

handler.removeCallbacks(myRunnable);

и ваш работающий способ определить таким образом

private Runnable myRunnable = new Runnable(){
      public void run(){
          // do something here
      }
}

http://developer.android.com/reference/android/os/Handler.html

http://developer.android.com/reference/java/util/logging/Handler.html

http://www.vogella.de/articles/AndroidPerformance/article.html

0 голосов
/ 12 июля 2011

В Java вы можете вызвать interrupt() в работающем потоке, который должен остановить выполнение данного потока.Но если выполняется какая-либо операция блокировки, например wait() или join(), будет выброшено InterruptedException.Даже некоторые виды операций блокировки, связанных с сокетами, могут привести к InterruptedIOException в Linux или в Windows, операция все еще остается заблокированной (поскольку Windows не поддерживает прерывистый ввод / вывод).Я думаю, что вы все еще можете прервать ваш работоспособный, просто имейте в виду, что некоторые операции ввода-вывода могут быть не прерваны до тех пор, пока они не будут завершены, и при блокировке могут возникнуть такие исключения, о которых я упоминал.

...