fix: requestScreenCapture() dead lock if request activity destroyed

This commit is contained in:
hyb1996 2018-03-15 20:22:13 +08:00
parent 9679830c75
commit 976e78e07d
4 changed files with 67 additions and 5 deletions

View File

@ -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() {

View File

@ -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

View File

@ -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);
}
}

View File

@ -42,6 +42,29 @@ public class VolatileDispose<T> {
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) {
synchronized (this) {
mValue = value;