在我的安卓应用程序中,我需要知道MapView缩放过程何时完成。没有内置的解决方案,所以我有了重写dispatchDraw的想法。
只要地图在缩放(以及在地图上滚动,但这并不重要),dispatchDraw就会被调用,我的想法是通过重写一个名为dispatchDrawInvoked的变量来不断检查dispatchDraw是否被调用。当第一次调用MapView上的缩放时(即缩放过程开始时),我启动了一个新线程,该线程每秒不断地将dispatchDrawInvoked设置为false。这个想法是,dispatchDraw方法在这一秒内多次用true重写dispatchDrawInvoked,当第二次重写结束而dispatchDraw仍然为true时,这意味着缩放还没有完成。在大多数情况下,在循环第二次运行之后,缩放完成并且dispatchDraw保持为假,因此它至少需要2秒。当循环识别到缩放过程已完成时,我将zoom变量设置为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;
}
}
}
}这是始终相同的日志。它表明没有并发:

发布于 2013-02-08 05:26:17
Runnable并不负责在线程上创建和执行,它只是提供线程在启动时将执行的run()方法。因此,您只是同步调用run()方法。你需要实际使用一些东西来启动另一个线程。
new Thread(new MapThread()).start()
我会照顾到你想要的东西,但是你应该重命名MapThread,因为它实际上只是一个runnable,如果你打算发布大量的runnable,并且不想为每个人创建一个线程,我建议你熟悉Handlers和HandlerThreads。
https://stackoverflow.com/questions/14760488
复制相似问题