fix: requestScreenCapture() dead lock if request activity destroyed
This commit is contained in:
@@ -3,6 +3,7 @@ package com.stardust.autojs;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
@@ -215,6 +216,16 @@ public abstract class AutoJs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester {
|
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)
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
@Override
|
@Override
|
||||||
public void request() {
|
public void request() {
|
||||||
|
|||||||
@@ -30,13 +30,23 @@ public class ScreenCaptureRequestActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private OnActivityResultDelegate.Mediator mOnActivityResultDelegateMediator = new OnActivityResultDelegate.Mediator();
|
private OnActivityResultDelegate.Mediator mOnActivityResultDelegateMediator = new OnActivityResultDelegate.Mediator();
|
||||||
|
private ScreenCaptureRequester mScreenCaptureRequester;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
ScreenCaptureRequester requester = new ScreenCaptureRequester.ActivityScreenCaptureRequester(mOnActivityResultDelegateMediator, this);
|
mScreenCaptureRequester = new ScreenCaptureRequester.ActivityScreenCaptureRequester(mOnActivityResultDelegateMediator, this);
|
||||||
requester.setOnActivityResultCallback(sCallback);
|
mScreenCaptureRequester.setOnActivityResultCallback(sCallback);
|
||||||
requester.request();
|
mScreenCaptureRequester.request();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (mScreenCaptureRequester == null)
|
||||||
|
return;
|
||||||
|
mScreenCaptureRequester.cancel();
|
||||||
|
mScreenCaptureRequester = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import com.stardust.app.OnActivityResultDelegate;
|
|||||||
|
|
||||||
public interface ScreenCaptureRequester {
|
public interface ScreenCaptureRequester {
|
||||||
|
|
||||||
|
void cancel();
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
|
|
||||||
void onRequestResult(int result, Intent data);
|
void onRequestResult(int result, Intent data);
|
||||||
@@ -28,11 +30,26 @@ public interface ScreenCaptureRequester {
|
|||||||
abstract class AbstractScreenCaptureRequester implements ScreenCaptureRequester {
|
abstract class AbstractScreenCaptureRequester implements ScreenCaptureRequester {
|
||||||
|
|
||||||
protected Callback mCallback;
|
protected Callback mCallback;
|
||||||
|
protected Intent mResult;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOnActivityResultCallback(Callback callback) {
|
public void setOnActivityResultCallback(Callback callback) {
|
||||||
mCallback = 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)
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
@@ -48,6 +65,7 @@ public interface ScreenCaptureRequester {
|
|||||||
mMediator.addDelegate(REQUEST_CODE_MEDIA_PROJECTION, this);
|
mMediator.addDelegate(REQUEST_CODE_MEDIA_PROJECTION, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void request() {
|
public void request() {
|
||||||
mActivity.startActivityForResult(((MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE)).createScreenCaptureIntent(), REQUEST_CODE_MEDIA_PROJECTION);
|
mActivity.startActivityForResult(((MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE)).createScreenCaptureIntent(), REQUEST_CODE_MEDIA_PROJECTION);
|
||||||
@@ -55,9 +73,9 @@ public interface ScreenCaptureRequester {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
mResult = data;
|
||||||
mMediator.removeDelegate(this);
|
mMediator.removeDelegate(this);
|
||||||
if (mCallback != null)
|
onResult(resultCode, data);
|
||||||
mCallback.onRequestResult(resultCode, data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,29 @@ public class VolatileDispose<T> {
|
|||||||
return mValue;
|
return mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T blockedGetOrThrow(Class<? extends RuntimeException> 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) {
|
public void setAndNotify(T value) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
mValue = value;
|
mValue = value;
|
||||||
|
|||||||
Reference in New Issue
Block a user