fix: images.captureScreen() return null or throw exception when called too often
This commit is contained in:
3
.idea/modules.xml
generated
3
.idea/modules.xml
generated
@@ -2,7 +2,8 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/Auto.js.iml" filepath="$PROJECT_DIR$/Auto.js.iml" />
|
<module fileurl="file://E:\YiBin\AndroidStudioProjects\NoRootScriptDroid\Auto.js.iml" filepath="E:\YiBin\AndroidStudioProjects\NoRootScriptDroid\Auto.js.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/NoRootScriptDroid.iml" filepath="$PROJECT_DIR$/NoRootScriptDroid.iml" />
|
||||||
<module fileurl="file://C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" filepath="C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" />
|
<module fileurl="file://C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" filepath="C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/autojs/autojs.iml" filepath="$PROJECT_DIR$/autojs/autojs.iml" />
|
<module fileurl="file://$PROJECT_DIR$/autojs/autojs.iml" filepath="$PROJECT_DIR$/autojs/autojs.iml" />
|
||||||
|
|||||||
@@ -32,13 +32,12 @@ public class ScreenCapturer {
|
|||||||
private VirtualDisplay mVirtualDisplay;
|
private VirtualDisplay mVirtualDisplay;
|
||||||
private volatile Looper mImageAcquireLooper;
|
private volatile Looper mImageAcquireLooper;
|
||||||
private final Object mImageWaitingLock = new Object();
|
private final Object mImageWaitingLock = new Object();
|
||||||
private volatile Image mImage;
|
private volatile Image mUnderUsingImage;
|
||||||
private volatile Image mLatestImage;
|
private volatile Image mCachedImage;
|
||||||
private final int mScreenWidth;
|
private final int mScreenWidth;
|
||||||
private final int mScreenHeight;
|
private final int mScreenHeight;
|
||||||
private final int mScreenDensity;
|
private final int mScreenDensity;
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
private volatile boolean mImageAvailable = false;
|
|
||||||
|
|
||||||
public ScreenCapturer(Context context, Intent data, int screenWidth, int screenHeight, int screenDensity, Handler handler) {
|
public ScreenCapturer(Context context, Intent data, int screenWidth, int screenHeight, int screenDensity, Handler handler) {
|
||||||
mScreenWidth = screenWidth;
|
mScreenWidth = screenWidth;
|
||||||
@@ -60,7 +59,7 @@ public class ScreenCapturer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initVirtualDisplay(MediaProjectionManager manager, Intent data, int screenWidth, int screenHeight, int screenDensity) {
|
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);
|
mMediaProjection = manager.getMediaProjection(Activity.RESULT_OK, data);
|
||||||
mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
|
mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
|
||||||
screenWidth, screenHeight, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
|
screenWidth, screenHeight, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
|
||||||
@@ -87,50 +86,23 @@ public class ScreenCapturer {
|
|||||||
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
|
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onImageAvailable(ImageReader reader) {
|
public void onImageAvailable(ImageReader reader) {
|
||||||
if (mImageAvailable) {
|
if (mCachedImage != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mLatestImage = reader.acquireLatestImage();
|
mCachedImage = reader.acquireLatestImage();
|
||||||
if (mLatestImage != null) {
|
|
||||||
mImageAvailable = true;
|
|
||||||
synchronized (mImageWaitingLock) {
|
|
||||||
mImageWaitingLock.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, handler);
|
}, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Image capture() {
|
public Image capture() {
|
||||||
if (!mImageAvailable) {
|
if (mCachedImage != null) {
|
||||||
waitForImageAvailable();
|
if (mUnderUsingImage != null)
|
||||||
return mLatestImage;
|
mUnderUsingImage.close();
|
||||||
}
|
mUnderUsingImage = mCachedImage;
|
||||||
if (mLatestImage != null) {
|
mCachedImage = 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return mUnderUsingImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScreenWidth() {
|
public int getScreenWidth() {
|
||||||
@@ -147,6 +119,9 @@ public class ScreenCapturer {
|
|||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
public void release() {
|
public void release() {
|
||||||
|
if (mImageAcquireLooper != null) {
|
||||||
|
mImageAcquireLooper.quit();
|
||||||
|
}
|
||||||
if (mMediaProjection != null) {
|
if (mMediaProjection != null) {
|
||||||
mMediaProjection.stop();
|
mMediaProjection.stop();
|
||||||
}
|
}
|
||||||
@@ -156,14 +131,20 @@ public class ScreenCapturer {
|
|||||||
if (mImageReader != null) {
|
if (mImageReader != null) {
|
||||||
mImageReader.close();
|
mImageReader.close();
|
||||||
}
|
}
|
||||||
if (mImageAcquireLooper != null) {
|
if (mUnderUsingImage != null) {
|
||||||
mImageAcquireLooper.quit();
|
mUnderUsingImage.close();
|
||||||
}
|
}
|
||||||
if (mImage != null) {
|
if (mCachedImage != null) {
|
||||||
mImage.close();
|
mCachedImage.close();
|
||||||
}
|
}
|
||||||
if (mLatestImage != null) {
|
}
|
||||||
mLatestImage.close();
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() throws Throwable {
|
||||||
|
try {
|
||||||
|
release();
|
||||||
|
} finally {
|
||||||
|
super.finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user