From bfd6a0c40ae24337bb898c1a8cdfba45984e14e5 Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Mon, 30 Oct 2017 19:05:57 +0800 Subject: [PATCH] fix: images.captureScreen() return null or throw exception when called too often --- .idea/modules.xml | 3 +- .../autojs/core/image/ScreenCapturer.java | 71 +++++++------------ 2 files changed, 28 insertions(+), 46 deletions(-) diff --git a/.idea/modules.xml b/.idea/modules.xml index f95bb89a..4fac18b4 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,8 @@ - + + diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCapturer.java b/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCapturer.java index d966fb8e..f23c0af5 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCapturer.java +++ b/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCapturer.java @@ -32,13 +32,12 @@ public class ScreenCapturer { private VirtualDisplay mVirtualDisplay; private volatile Looper mImageAcquireLooper; private final Object mImageWaitingLock = new Object(); - private volatile Image mImage; - private volatile Image mLatestImage; + private volatile Image mUnderUsingImage; + private volatile Image mCachedImage; private final int mScreenWidth; private final int mScreenHeight; private final int mScreenDensity; private Handler mHandler; - private volatile boolean mImageAvailable = false; public ScreenCapturer(Context context, Intent data, int screenWidth, int screenHeight, int screenDensity, Handler handler) { mScreenWidth = screenWidth; @@ -60,7 +59,7 @@ public class ScreenCapturer { } private void initVirtualDisplay(MediaProjectionManager manager, Intent data, int screenWidth, int screenHeight, int screenDensity) { - mImageReader = ImageReader.newInstance(screenWidth, screenHeight, PixelFormat.RGBA_8888, 1); + mImageReader = ImageReader.newInstance(screenWidth, screenHeight, PixelFormat.RGBA_8888, 2); mMediaProjection = manager.getMediaProjection(Activity.RESULT_OK, data); mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror", screenWidth, screenHeight, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, @@ -87,50 +86,23 @@ public class ScreenCapturer { mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { - if (mImageAvailable) { + if (mCachedImage != null) { return; } - mLatestImage = reader.acquireLatestImage(); - if (mLatestImage != null) { - mImageAvailable = true; - synchronized (mImageWaitingLock) { - mImageWaitingLock.notify(); - } - } + mCachedImage = reader.acquireLatestImage(); } }, handler); } @Nullable public Image capture() { - if (!mImageAvailable) { - waitForImageAvailable(); - return mLatestImage; - } - if (mLatestImage != null) { - tryClose(mLatestImage); - } - mLatestImage = mImageReader.acquireLatestImage(); - return mLatestImage; - } - - private void tryClose(Image image) { - try { - image.close(); - } catch (Exception ignored) { - - } - } - - private void waitForImageAvailable() { - Log.d(LOG_TAG, "waitForImageAvailable"); - synchronized (mImageWaitingLock) { - try { - mImageWaitingLock.wait(); - } catch (InterruptedException e) { - throw new ScriptInterruptedException(); - } + if (mCachedImage != null) { + if (mUnderUsingImage != null) + mUnderUsingImage.close(); + mUnderUsingImage = mCachedImage; + mCachedImage = null; } + return mUnderUsingImage; } public int getScreenWidth() { @@ -147,6 +119,9 @@ public class ScreenCapturer { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void release() { + if (mImageAcquireLooper != null) { + mImageAcquireLooper.quit(); + } if (mMediaProjection != null) { mMediaProjection.stop(); } @@ -156,14 +131,20 @@ public class ScreenCapturer { if (mImageReader != null) { mImageReader.close(); } - if (mImageAcquireLooper != null) { - mImageAcquireLooper.quit(); + if (mUnderUsingImage != null) { + mUnderUsingImage.close(); } - if (mImage != null) { - mImage.close(); + if (mCachedImage != null) { + mCachedImage.close(); } - if (mLatestImage != null) { - mLatestImage.close(); + } + + @Override + protected void finalize() throws Throwable { + try { + release(); + } finally { + super.finalize(); } } }