ScreenshotUtil實現
最近多次在項目中用到截圖功能,于是封裝了一個截圖工具,使用MediaProjection實現截圖,權限申請使用了RxActivityResult。
使用方法:
- 在Application中注冊
public class MyApp extends Application {
@Override public void onCreate() {
super.onCreate();
ScreenshotUtil.register(this);
}
}
- 在on方法中傳入Activity 對象,在subscribe中處理截圖的結果Bitmap
ScreenshotUtil.on(this).takeScreenshot().subscribe(bitmap -> { if (bitmap == null) {
Log.e(TAG, "Bitmap is null.");
} else {
mImageView.setImageBitmap(bitmap);
}});
Github: https://github.com/MissMidou/Android-Develop-Tool
RxActivityResult 實現原理
在startActivityForResult 時,需要在onActivityResult 中處理返回結果,而使用RxActivityResult,可以不用重寫onActivityResult來直接處理返回結果,代碼簡介清晰。
Github: https://github.com/VictorAlbertos/RxActivityResult
使用范例:
public class SampleApp extends Application {
@Override public void onCreate() {
super.onCreate();
RxActivityResult.register(this);
}
}
RxActivityResult.register(this);用于判斷在頂層的Activity的生命周期,用這個Activity打開目標Activity
Intent takePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
RxActivityResult.on(this).startIntent(takePhoto)
.subscribe(result -> {
Intent data = result.data();
int resultCode = result.resultCode();
// the requestCode using which the activity is started can be received here.
int requestCode = result.requestCode();
if(requestCode == YourActivity.YOUR_REQUEST_CODE)
{
// Do Something
}
if (resultCode == RESULT_OK) {
result.targetUI().showImage(data);
} else {
result.targetUI().printUserCanceled();
}
});
on()返回一個Builder 對象,Builder中創建一個PublishSubject實例,PublishSubject與普通Observable相比,Observable是訂閱時立即觸發訂閱事件,而PublishSubject可以在任意時刻調用onNext,onComplete方法觸發訂閱事件,觀察者在訂閱之后便可以收到事件,這里在onActivityResult返回結果后,觸發訂閱事件
public static <T extends Activity> Builder<T> on(T activity) {
return new Builder<T>(activity);
}
public static class Builder<T> {
final Class clazz;
final PublishSubject<Result<T>> subject = PublishSubject.create();
private final boolean uiTargetActivity;
... ...
}
startIntent()調用startHolderActivity,通過打開一個HolderActivity,然后在HolderActivity中打開目標Activity,并在onActivityResult處理結果
private Observable<Result<T>> startHolderActivity(Request request, @Nullable OnPreResult onPreResult) {
OnResult onResult = uiTargetActivity ? onResultActivity() : onResultFragment();
request.setOnResult(onResult);
request.setOnPreResult(onPreResult);
HolderActivity.setRequest(request);
//getOLiveActivity找到頂層Activity,因為在Fragment中打開的時候需要Activity
activitiesLifecycle.getOLiveActivity().subscribe(new Consumer<Activity>() {
@Override
public void accept(Activity activity) throws Exception {
activity.startActivity(new Intent(activity, HolderActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
}
});
return subject;
}
HolderActivity打開目標Activity后,onActivityResult中保存結果并finish,然后onDestroy 中發射訂閱事件
HolderActivity.java
@Override
protected void onDestroy() {
super.onDestroy();
if (onResult != null)
onResult.response(requestCode, resultCode, data);
}
private OnResult onResultActivity() {
return new OnResult() {
@Override
public void response(int requestCode, int resultCode, Intent data) {
if (activitiesLifecycle.getLiveActivity() == null) return;
//If true it means some other activity has been stacked as a secondary process.
//Wait until the current activity be the target activity
if (activitiesLifecycle.getLiveActivity().getClass() != clazz) {
return;
}
T activity = (T) activitiesLifecycle.getLiveActivity();
subject.onNext(new Result<>(activity, requestCode, resultCode, data));
subject.onComplete();
}
@Override
public void error(Throwable throwable) {
subject.onError(throwable);
}
};
}