From 976e78e07d786f2cf217c1d20fa27c517308f1b9 Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Thu, 15 Mar 2018 20:22:13 +0800 Subject: [PATCH] fix: requestScreenCapture() dead lock if request activity destroyed --- .../main/java/com/stardust/autojs/AutoJs.java | 11 +++++++++ .../image/ScreenCaptureRequestActivity.java | 16 ++++++++++--- .../core/image/ScreenCaptureRequester.java | 22 ++++++++++++++++-- .../stardust/concurrent/VolatileDispose.java | 23 +++++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/autojs/src/main/java/com/stardust/autojs/AutoJs.java b/autojs/src/main/java/com/stardust/autojs/AutoJs.java index 87fc1a91..51022c5c 100644 --- a/autojs/src/main/java/com/stardust/autojs/AutoJs.java +++ b/autojs/src/main/java/com/stardust/autojs/AutoJs.java @@ -3,6 +3,7 @@ package com.stardust.autojs; import android.app.Activity; import android.app.Application; import android.content.Context; +import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; @@ -215,6 +216,16 @@ public abstract class AutoJs { } private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester { + + + @Override + public void setOnActivityResultCallback(Callback callback) { + super.setOnActivityResultCallback((result, data) -> { + mResult = data; + callback.onRequestResult(result, data); + }); + } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void request() { diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequestActivity.java b/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequestActivity.java index b87ef052..5ee73af0 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequestActivity.java +++ b/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequestActivity.java @@ -30,13 +30,23 @@ public class ScreenCaptureRequestActivity extends Activity { } private OnActivityResultDelegate.Mediator mOnActivityResultDelegateMediator = new OnActivityResultDelegate.Mediator(); + private ScreenCaptureRequester mScreenCaptureRequester; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ScreenCaptureRequester requester = new ScreenCaptureRequester.ActivityScreenCaptureRequester(mOnActivityResultDelegateMediator, this); - requester.setOnActivityResultCallback(sCallback); - requester.request(); + mScreenCaptureRequester = new ScreenCaptureRequester.ActivityScreenCaptureRequester(mOnActivityResultDelegateMediator, this); + mScreenCaptureRequester.setOnActivityResultCallback(sCallback); + mScreenCaptureRequester.request(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mScreenCaptureRequester == null) + return; + mScreenCaptureRequester.cancel(); + mScreenCaptureRequester = null; } @Override diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequester.java b/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequester.java index 91707757..828bb6f2 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequester.java +++ b/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequester.java @@ -15,6 +15,8 @@ import com.stardust.app.OnActivityResultDelegate; public interface ScreenCaptureRequester { + void cancel(); + interface Callback { void onRequestResult(int result, Intent data); @@ -28,11 +30,26 @@ public interface ScreenCaptureRequester { abstract class AbstractScreenCaptureRequester implements ScreenCaptureRequester { protected Callback mCallback; + protected Intent mResult; @Override public void setOnActivityResultCallback(Callback callback) { mCallback = callback; } + + public void onResult(int resultCode, Intent data) { + mResult = data; + if (mCallback != null) + mCallback.onRequestResult(resultCode, data); + } + + @Override + public void cancel() { + if (mResult != null) + return; + if (mCallback != null) + mCallback.onRequestResult(Activity.RESULT_CANCELED, null); + } } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @@ -48,6 +65,7 @@ public interface ScreenCaptureRequester { mMediator.addDelegate(REQUEST_CODE_MEDIA_PROJECTION, this); } + @Override public void request() { mActivity.startActivityForResult(((MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE)).createScreenCaptureIntent(), REQUEST_CODE_MEDIA_PROJECTION); @@ -55,9 +73,9 @@ public interface ScreenCaptureRequester { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { + mResult = data; mMediator.removeDelegate(this); - if (mCallback != null) - mCallback.onRequestResult(resultCode, data); + onResult(resultCode, data); } } diff --git a/common/src/main/java/com/stardust/concurrent/VolatileDispose.java b/common/src/main/java/com/stardust/concurrent/VolatileDispose.java index 4c3ffa21..d92e6f68 100644 --- a/common/src/main/java/com/stardust/concurrent/VolatileDispose.java +++ b/common/src/main/java/com/stardust/concurrent/VolatileDispose.java @@ -42,6 +42,29 @@ public class VolatileDispose { return mValue; } + public T blockedGetOrThrow(Class exception, long timeout, T defaultValue) { + synchronized (this) { + if (mValue != null) { + return mValue; + } + try { + this.wait(timeout); + } catch (InterruptedException e) { + try { + throw exception.newInstance(); + } catch (InstantiationException e1) { + throw new RuntimeException(e1); + } catch (IllegalAccessException e1) { + throw new RuntimeException(e1); + } + } + if (mValue == null) { + return defaultValue; + } + } + return mValue; + } + public void setAndNotify(T value) { synchronized (this) { mValue = value;