1

我正在使用这个来显示照片(我不想使用PhotoView库,因为它没有我需要的)。这个库是完美的,但只有一个缺点:当改变屏幕方向时,它会使屏幕变白,并在几毫秒内重新加载图像......我玩过代码,SubsamplingScaleImageView发现这三个中有一些方法AsyncTask' sdoInBackground中操作所需的方法uiThread

当我使用该代码时,我已经将所有内容从doInBackground方法移动到postExecute每个AsyncTask类中并编译程序。令我惊讶的是一切工作正常,我决定撤消所有操作并更仔细地使用该代码进行操作,但在那之后它没有工作,即使我试图postExecute再次将代码移动到......我不记得我是如何将该代码移入,onPostExecute但它一直在工作,直到我决定重构它(((请任何人帮助我!

   /**
     * Async task used to get image details without blocking the UI thread.
     */
    private static class TilesInitTask extends AsyncTask<Void, Void, int[]> {
        private final WeakReference<SubsamplingScaleImageView> viewRef;
        private final WeakReference<Context> contextRef;
        private final WeakReference<DecoderFactory<? extends ImageRegionDecoder>> decoderFactoryRef;
        private final Uri source;
        private ImageRegionDecoder decoder;
        private Exception exception;

        public TilesInitTask(SubsamplingScaleImageView view, Context context, DecoderFactory<? extends ImageRegionDecoder> decoderFactory, Uri source) {
            this.viewRef = new WeakReference<SubsamplingScaleImageView>(view);
            this.contextRef = new WeakReference<Context>(context);
            this.decoderFactoryRef = new WeakReference<DecoderFactory<? extends ImageRegionDecoder>>(decoderFactory);
            this.source = source;
        }

        @Override
        protected int[] doInBackground(Void... params) {
            try {
                String sourceUri = source.toString();
                Context context = contextRef.get();
                DecoderFactory<? extends ImageRegionDecoder> decoderFactory = decoderFactoryRef.get();
                SubsamplingScaleImageView view = viewRef.get();
                if (context != null && decoderFactory != null && view != null) {
                    decoder = decoderFactory.make();
                    Point dimensions = decoder.init(context, source);
                    int sWidth = dimensions.x;
                    int sHeight = dimensions.y;
                    int exifOrientation = view.getExifOrientation(sourceUri);
                    if (view.sRegion != null) {
                        sWidth = view.sRegion.width();
                        sHeight = view.sRegion.height();
                    }
                    return new int[] { sWidth, sHeight, exifOrientation };
                }
            } catch (Exception e) {
                Log.e(TAG, "Failed to initialise bitmap decoder", e);
                this.exception = e;
            }
            return null;
        }

        @Override
        protected void onPostExecute(int[] xyo) {
            final SubsamplingScaleImageView view = viewRef.get();
            if (view != null) {
                if (decoder != null && xyo != null && xyo.length == 3) {
                    view.onTilesInited(decoder, xyo[0], xyo[1], xyo[2]);
                } else if (exception != null && view.onImageEventListener != null) {
                    view.onImageEventListener.onImageLoadError(exception);
                }
            }
        }
    }

    /**
     * Async task used to load images without blocking the UI thread.
     */
    private static class TileLoadTask extends AsyncTask<Void, Void, Bitmap> {
        private final WeakReference<SubsamplingScaleImageView> viewRef;
        private final WeakReference<ImageRegionDecoder> decoderRef;
        private final WeakReference<Tile> tileRef;
        private Exception exception;

        public TileLoadTask(SubsamplingScaleImageView view, ImageRegionDecoder decoder, Tile tile) {
            this.viewRef = new WeakReference<SubsamplingScaleImageView>(view);
            this.decoderRef = new WeakReference<ImageRegionDecoder>(decoder);
            this.tileRef = new WeakReference<Tile>(tile);
            tile.loading = true;
        }

        @Override
        protected Bitmap doInBackground(Void... params) {
            try {
                SubsamplingScaleImageView view = viewRef.get();
                ImageRegionDecoder decoder = decoderRef.get();
                Tile tile = tileRef.get();
                if (decoder != null && tile != null && view != null && decoder.isReady()) {
                    synchronized (view.decoderLock) {
                        // Update tile's file sRect according to rotation
                        view.fileSRect(tile.sRect, tile.fileSRect);
                        if (view.sRegion != null) {
                            tile.fileSRect.offset(view.sRegion.left, view.sRegion.top);
                        }
                        return decoder.decodeRegion(tile.fileSRect, tile.sampleSize);
                    }
                } else if (tile != null) {
                    tile.loading = false;
                }
            } catch (Exception e) {
                Log.e(TAG, "Failed to decode tile", e);
                this.exception = e;
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            final SubsamplingScaleImageView subsamplingScaleImageView = viewRef.get();
            final Tile tile = tileRef.get();
            if (subsamplingScaleImageView != null && tile != null) {
                if (bitmap != null) {
                    tile.bitmap = bitmap;
                    tile.loading = false;
                    subsamplingScaleImageView.onTileLoaded();
                } else if (exception != null && subsamplingScaleImageView.onImageEventListener != null) {
                    subsamplingScaleImageView.onImageEventListener.onTileLoadError(exception);
                }
            }
        }
    }

UPD

现在我刚刚更改AsyncTasksRunnable并通过run()没有Handler(getMainLooper()).post(runnable). 有人可以解释一下发生了什么吗?


   /**
         * Async task used to get image details without blocking the UI thread.
         */
        private static class TilesInitTask implements Runnable {
            private final WeakReference<SubsamplingScaleImageView> viewRef;
            private final WeakReference<Context> contextRef;
            private final WeakReference<DecoderFactory<? extends ImageRegionDecoder>> decoderFactoryRef;
            private final Uri source;
            private ImageRegionDecoder decoder;
            private Exception exception;

            public TilesInitTask(SubsamplingScaleImageView view, Context context, DecoderFactory<? extends ImageRegionDecoder> decoderFactory, Uri source) {
                this.viewRef = new WeakReference<>(view);
                this.contextRef = new WeakReference<>(context);
                this.decoderFactoryRef = new WeakReference<DecoderFactory<? extends ImageRegionDecoder>>(decoderFactory);
                this.source = source;
            }

            public void run() {
                SubsamplingScaleImageView view = null;
                try {
                    String sourceUri = source.toString();
                    Context context = contextRef.get();
                    DecoderFactory<? extends ImageRegionDecoder> decoderFactory = decoderFactoryRef.get();
                    view = viewRef.get();
                    if (context != null && decoderFactory != null && view != null) {
                        decoder = decoderFactory.make();
                        Point dimensions = decoder.init(context, source);
                        int sWidth = dimensions.x;
                        int sHeight = dimensions.y;

                        int exifOrientation = view.getExifOrientation(sourceUri);
                        if (view.sRegion != null) {
                            sWidth = view.sRegion.width();
                            sHeight = view.sRegion.height();
                        }
                        view.onTilesInited(decoder, sWidth, sHeight, exifOrientation);
                    }
                } catch (Exception e) {
                    Log.e(TAG, "Failed to initialise bitmap decoder", e);
                    this.exception = e;
                    if (view != null && view.onImageEventListener != null) {
                        view.onImageEventListener.onImageLoadError(exception);
                    }
                }
            }
        }

/**
     * Async task used to load images without blocking the UI thread.
     */
    private static class TileLoadTask implements Runnable {
        private final WeakReference<SubsamplingScaleImageView> viewRef;
        private final WeakReference<ImageRegionDecoder> decoderRef;
        private final WeakReference<Tile> tileRef;
        private Exception exception;

        public TileLoadTask(SubsamplingScaleImageView view, ImageRegionDecoder decoder, Tile tile) {
            this.viewRef = new WeakReference<>(view);
            this.decoderRef = new WeakReference<>(decoder);
            this.tileRef = new WeakReference<>(tile);
            tile.loading = true;
        }

        public void run() {
            SubsamplingScaleImageView view = null;
            try {
                view = viewRef.get();
                ImageRegionDecoder decoder = decoderRef.get();
                Tile tile = tileRef.get();
                if (decoder != null && tile != null && view != null && decoder.isReady()) {
                    synchronized (view.decoderLock) {
                        // Update tile's file sRect according to rotation
                        view.fileSRect(tile.sRect, tile.fileSRect);
                        Log.d("TAGTAG", "2");
                        if (view.sRegion != null) {
                            tile.fileSRect.offset(view.sRegion.left, view.sRegion.top);
                        }
                        tile.bitmap = decoder.decodeRegion(tile.fileSRect, tile.sampleSize);
                        tile.loading = false;
                        view.onTileLoaded();
                    }
                } else if (tile != null) {
                    tile.loading = false;
                }
            } catch (Exception e) {
                Log.e(TAG, "Failed to decode tile", e);
                this.exception = e;
                if (view != null && view.onImageEventListener != null) {
                    view.onImageEventListener.onTileLoadError(exception);
                }
            }
        }
    }
4

0 回答 0