显示lib的ImageView提高了性能

时间:2015-09-21 18:31:34

标签: android android-asynctask android-runonuithread

我使用此lib来显示照片(我不想使用PhotoView lib,因为它没有我需要的东西。这个lib很完美,但只有一个减号:当改变屏幕方向时,它会使屏幕变白并在几毫秒内重新加载图像...我已经使用了SubsamplingScaleImageView的代码并发现了那里是在AsyncTask中操作所需的三种doInBackground 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

现在我已将AsyncTasks更改为Runnable,并在没有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);
                }
            }
        }
    }

0 个答案:

没有答案