首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android:并发性确实具有顺序行为

Android:并发性确实具有顺序行为
EN

Stack Overflow用户
提问于 2013-02-08 04:34:49
回答 1查看 105关注 0票数 0

在我的安卓应用程序中,我需要知道MapView缩放过程何时完成。没有内置的解决方案,所以我有了重写dispatchDraw的想法。

只要地图在缩放(以及在地图上滚动,但这并不重要),dispatchDraw就会被调用,我的想法是通过重写一个名为dispatchDrawInvoked的变量来不断检查dispatchDraw是否被调用。当第一次调用MapView上的缩放时(即缩放过程开始时),我启动了一个新线程,该线程每秒不断地将dispatchDrawInvoked设置为false。这个想法是,dispatchDraw方法在这一秒内多次用true重写dispatchDrawInvoked,当第二次重写结束而dispatchDraw仍然为true时,这意味着缩放还没有完成。在大多数情况下,在循环第二次运行之后,缩放完成并且dispatchDraw保持为假,因此它至少需要2秒。当循环识别到缩放过程已完成时,我将zoom变量设置为true,以通知(需要知道这一点的上层类)缩放已完成。

到目前一切尚好。问题是,整个实现并不是并发的。它的行为是连续的,并且MapView被卡住了2秒。为什么会这样,请看我的代码:

代码语言:javascript
复制
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;
            }
        }
    }
}

这是始终相同的日志。它表明没有并发:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-08 05:26:17

Runnable并不负责在线程上创建和执行,它只是提供线程在启动时将执行的run()方法。因此,您只是同步调用run()方法。你需要实际使用一些东西来启动另一个线程。

new Thread(new MapThread()).start()

我会照顾到你想要的东西,但是你应该重命名MapThread,因为它实际上只是一个runnable,如果你打算发布大量的runnable,并且不想为每个人创建一个线程,我建议你熟悉HandlersHandlerThreads

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14760488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档