Заставьте Android MainActivity ждать завершения потока

Я изучаю Google Maps Android Api v2 и обнаружил некоторые проблемы, с которыми я возился!

Я работаю с массивом LatLng, содержащим маршрут из файла XML.

Я хочу, чтобы приложение имитировало поездку на автомобиле с импортированными данными. (покажите простой маркер, показывающий «текущую» позицию внутри массива в цикле)

Я нашел метод, который анимирует маркер из одной точки в другую. Это неплохо работает, когда я просто работаю с двумя координатами, но сходит с ума, когда я работаю со всем массивом!

Я предполагаю, что это потому, что обработчик в методе animateMarker.

Итак, мой вопрос: как я могу заставить основной поток ждать завершения animateMarker, чтобы правильно увидеть смоделированный маршрут.

Спасибо.

Вот код:

public class MainActivity extends Activity {

GoogleMap mMap;
ArrayList<LatLng> coordinates;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    /**
     * Here I import the LatLng array from an XML file
     */


    mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

    Marker myMarker;

    myMarker = mMap.addMarker(new MarkerOptions()
    .position(coordinates.get(0)));

    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates.get(0),17));

    for(int i=0;i<coordinates.size()-1;i++){
         animateMarker(myMarker, coordinates.get(i+1), false);
         mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates.get(i),17));
    }


 }

/**
 * 
 * @param marker
 * @param toPosition
 * @param hideMarker
 * @return 
 */
public  void animateMarker(final Marker marker, final LatLng toPosition,
        final boolean hideMarker) {

    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    final LatLng startLatLng= marker.getPosition();
    final long duration = 2000;

    final Interpolator interpolator = new LinearInterpolator();
    handler.post(new Runnable() {
        @Override
        public void  run() {
            long elapsed = SystemClock.uptimeMillis() - start;
            float t = interpolator.getInterpolation((float) elapsed
                    / duration);
            double lng = t * toPosition.longitude + (1 - t)
                    * startLatLng.longitude;
            double lat = t * toPosition.latitude + (1 - t)
                    * startLatLng.latitude;
            marker.setPosition(new LatLng(lat, lng));

            if (t < 1.0) {
                // Post again 16ms later.
                handler.postDelayed(this, 16);
            } else {
                if (hideMarker) {
                    marker.setVisible(false);
                } else {
                    marker.setVisible(true);
                }

            }
        }

    });

}

 }

person Jorge B.    schedule 20.10.2014    source источник


Ответы (1)


использовать AsyncTask

вот пример

     private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
         protected Long doInBackground(URL... urls) {
             int count = urls.length;
             long totalSize = 0;
             for (int i = 0; i < count; i++) {
                 totalSize += Downloader.downloadFile(urls[i]);
                 publishProgress((int) ((i / (float) count) * 100));
                 // Escape early if cancel() is called
                 if (isCancelled()) break;
             }
             return totalSize;
         }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

После создания задача выполняется очень просто:

new DownloadFilesTask().execute(url1, url2, url3);
person Anas Alaa    schedule 20.10.2014
comment
Я пробовал, но что вы имеете в виду? Включая цикл for внутри метода doInBackground? или просто залить его нить. сна ?? - person Jorge B.; 24.10.2014