之前运用过Fragment对Android动态运行时权限进行封装,避免了每次都需要onRequestPermissionsResult 回调处理。同理,也可以用同样的方式对 Activity的onActivityResult 回调进行封装。常用的想到了调用系统相机进行拍摄以及获取系统相册的图片。
RouterFragment 中间层
RouterFragment 起到一个中间层的作用。主要用来发起请求和接收回调,通过回调接口,将数据结果回调到调用类。先来看看 RouterFragment 主要代码。
- createRequestCode
随机生成一定范围内的code,用于和回调的Callback进行一对一的缓存
private int createRequestCode() {
int requestCode;
int tryCount = 0;
do {
requestCode = mCodeGenerator.nextInt(0x0000FFFF);
tryCount++;
} while (mCallBacks.indexOfKey(requestCode) >= 0 && tryCount < MAX_TRY_COUNT);
return requestCode;
}
- startActivityforResult
调用跳转的地方,并且将Callback进行缓存
public void startActivityforResult(Intent intent, CaptureHelper.Callback callback){
int requestCode = createRequestCode();
mCallBacks.put(requestCode, callback);
startActivityForResult(intent, requestCode);
}
- onActivityResult
这个就是关键要处理的地方了,取出之前缓存的Callback,将请求结果回调到对应的code的请求中。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
CaptureHelper.Callback callback = mCallBacks.get(requestCode);
mCallBacks.remove(requestCode);
if (callback != null) {
callback.onActivityResult(requestCode, resultCode, data);
}
}
CaptureHelper
该类主要用于处理相机调用和系统相册的调用
之前在用封装好的运行时权限库的时候,leakcanary 报出了Activity引用内存泄漏的风险,所以在Activity引用中使用了 弱引用进行优化。
public CaptureHelper init(FragmentActivity activity){
mWeakActivityRef = new WeakReference<>(activity);
return SingletonHolder.INSTANCE;
}
开启系统相机进行拍照 requestCapture
调用同时也考虑了对7.0系统的适配兼容。(7.0相机适配网上很多,这里就不细说了)
直接上代码:
/**
* 打开相机进行拍照
* @param savePath
*/
public void requestCapture(String savePath){
final File captureFile = new File(savePath);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri photoURI = null;
if(captureFile != null){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
photoURI = FileProvider.getUriForFile(mWeakActivityRef.get(),
"com.qhh.baselib.image.provider",
captureFile);
//这段代码主要是拍照之后保存在临时路径上
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
}else{
//7.0以下使用这种方式创建一个Uri
photoURI = Uri.fromFile(captureFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
}
}
//通过中间层的Fragment请求并且回调数据,最终在工具类中再往上层进行回调
getFragment().startActivityforResult(intent, new Callback() {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK){
String path = captureFile.getAbsolutePath();
if(mIRequestCaptureCallback != null)
mIRequestCaptureCallback.success(resultCode,path);
}else{
if(mIRequestCaptureCallback != null)
mIRequestCaptureCallback.error(resultCode);
}
}
});
getFragment 主要用于获取中间层的Fragment
private RouterFragment getFragment(){
FragmentManager manager = mWeakActivityRef.get().getSupportFragmentManager();
RouterFragment fragment = (RouterFragment)manager.findFragmentByTag(REQUEST_CAPTURE);
if(fragment == null){
fragment = RouterFragment.getInstance();
manager.beginTransaction()
.add(fragment,REQUEST_CAPTURE)
.commitAllowingStateLoss();
manager.executePendingTransactions();
}
return fragment;
}
最后
上边主要是简单的展示代码,实现原理比较的简单,通过封装可以以后自己用的时候方便一些,最后放到了Jitpack上。详细的使用可以参考我github上的源码和readme。
https://github.com/qinhaihang/BaseLib
网友评论