在我的Android應用程序中,我需要知道MapView縮放過程何時完成。沒有內置的解決方案,所以我有想法重寫dispatchDraw。Android:併發確實表現順序
只要Map縮放(以及在Map上滾動,但這並不重要),就會調用dispatchDraw,我的想法是不斷檢查dispatchDraw是否通過覆蓋名爲dispatchDrawInvoked的變量來調用。當第一次調用MapView上的縮放時(這意味着縮放過程開始時),我開始一個新的線程,該線程每秒連續設置dispatchDrawInvoked爲false。這個想法是,dispatchDraw方法在這秒鐘內用很多次覆蓋dispatchDrawInvoked,當第二個結束並且dispatchDraw仍然爲true時,這意味着縮放還沒有完成。在大多數情況下,縮放完成,並且dispatchDraw在循環第二次運行後保持爲假,因此最少需要2秒。當循環識別出縮放過程完成時,我將縮放變量設置爲true以向信號發送(對於需要知道的上級類別)縮放已完成。
到目前爲止這麼好。問題是,這整個實現不表現併發。它的行爲是順序的,MapView卡住了2秒鐘。爲什麼是這樣,請看我的代碼:
public class ZoomListeningMapView extends MapView {
private final static String TAG = ZoomListeningMapView.class.getSimpleName();
private final static int DEFAULT_ZOOM_LEVEL = 14;
private int lastZoomLevel = DEFAULT_ZOOM_LEVEL;
private volatile boolean zooming = false;
private volatile boolean dispatchDrawInvoked = false;
public ZoomListeningMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ZoomListeningMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ZoomListeningMapView(Context context, String apiKey) {
super(context, apiKey);
}
public boolean isZooming() {
return zooming;
}
public static int getDefaultZoomLevel() {
return DEFAULT_ZOOM_LEVEL;
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
dispatchDrawInvoked = true;
Log.i(TAG, "setting dispatchDrawInvoked to true");
Log.i(TAG, "zooming:" + zooming);
if (getZoomLevel() != lastZoomLevel) {
lastZoomLevel = getZoomLevel();
Log.i(TAG, "zoom level changed");
zooming = true;
Log.i(TAG, "zooming:" + zooming);
new Thread(new ZoomRunnable()).start();
}
}
private class ZoomRunnable implements Runnable {
private final String TAG = ZoomRunnable.class.getSimpleName();
@Override
public void run() {
try {
while (zooming) {
dispatchDrawInvoked = false;
Log.i(TAG, "setting dispatchDrawInvoked to false");
Thread.sleep(1000);
if (dispatchDrawInvoked == false) {
zooming = false;
Log.i(TAG, "dispatchDrawInvoked is still false, so Map zooming is finished.");
}
}
}
catch (InterruptedException e) {
Log.e(TAG, "InterruptedException: " + e.getMessage());
return;
}
}
}
}
這是總是相同的日誌。這表明,沒有併發問題:
謝謝,這個工程(在我不得不對run方法做一些修改之後)。我將MapThread更名爲ZoomRunnable。 – Bevor