Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/185.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:并发的行为是连续的_Android_Multithreading_Concurrency_Android Mapview - Fatal编程技术网

Android:并发的行为是连续的

Android:并发的行为是连续的,android,multithreading,concurrency,android-mapview,Android,Multithreading,Concurrency,Android Mapview,在我的Android应用程序中,我需要知道MapView缩放过程何时完成。没有内置的解决方案,所以我想覆盖dispatchDraw 只要地图在缩放(以及地图上的一个滚动,但这并不重要),就会调用dispatchDraw,我的想法是通过覆盖名为DispatchDrawInvocated的变量来持续检查是否调用了dispatchDraw。当MapView上的缩放第一次被调用时(这意味着当缩放过程开始时),我启动一个新线程,该线程持续地将DispatchDrawCalled every设置为false

在我的Android应用程序中,我需要知道MapView缩放过程何时完成。没有内置的解决方案,所以我想覆盖dispatchDraw

只要地图在缩放(以及地图上的一个滚动,但这并不重要),就会调用dispatchDraw,我的想法是通过覆盖名为DispatchDrawInvocated的变量来持续检查是否调用了dispatchDraw。当MapView上的缩放第一次被调用时(这意味着当缩放过程开始时),我启动一个新线程,该线程持续地将DispatchDrawCalled every设置为false。其思想是,dispatchDraw方法在这一秒内多次覆盖使用true调用的dispatchDraw,当第二次结束且dispatchDraw仍然为true时,这意味着缩放尚未完成。在大多数情况下,在循环运行第二次后,缩放完成,dispatchDraw保持为false,因此至少需要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;
            }
        }
    }
}
这是始终相同的日志。这表明没有并发:


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

新线程(new-MapThread()).start()


将处理您想要的内容,但您应该重命名MapThread,因为它实际上只是一个可运行的,我建议您熟悉它,如果您打算发布很多可运行的,并且不想为每个可运行的都创建一个线程。

可运行的并不负责在线程上创建和执行,它只提供运行()方法,线程在启动时将执行该方法。所以您只是同步调用run()方法。您需要实际使用能够启动另一个线程的东西

新线程(new-MapThread()).start()

我会注意你想要的,但是你应该重命名MapThread,因为它实际上只是一个可运行的,我建议你熟悉它,如果你想发布很多可运行的,并且不想为每个都创建一个线程。

谢谢,这很有效(在我不得不对run方法做一些修改之后)。我将MapThread重命名为ZoomRunnable。谢谢,这很有效(在我对run方法做了一些修改之后)。我将MapThread重命名为ZoomRunnable。