当Activity A启动一个Activity B后,B finish,我们可能需要处理B返回的值,此时,我们可能就需要用到了onActivityResult,需要在Activity A中重写实现。 当然,在这种前提是我们处理逻辑都是放在Activity A类中,那么假如我们是在一个其他类,不是Activity或者Fragment的情况呢?
此时,我们可能会用到EventBus
这种全局分发事件的方式来处理,但种感觉不够优雅。
当我看到Google的开源的lifecycle库中的HolderFragment
的做法,感觉眼前一亮。在Activity
或者Fragment
中添加一个空壳的Fragment
,作为一个生命周期的监听。
同样的,开源库Glide
也有相似的设计。
这种方法挺好的。
所以我产生以下思路:通过给当前的Activity
添加一个空壳的Fragment
,往空壳的Fragment
中传入Listener
,然后由该Fragment
去启动新的Activity
,最终在这个空壳的Fragment
的onActivityResult
中将结果传到Listener
返回出去。
1、 首先,我们对外暴露一个Fragment
需要实现的接口,让外部使用这个接口,而不是直接使用这个Fragment
,做接口隔离。
public interface ListenActivityResultRequest {
void startActivity(Intent intent, int requestCode, OnActivityResultCallBack callBack);
interface OnActivityResultCallBack {
void onActivityResult(int resultCode, Intent data);
}
}
该接口的方法提供一个startActivity
,让外部传入intent
和requestCode
,还有处理onActivityReuslt
的回调OnActivityResultCallBack
2、空壳Fragment
的实现
(1)创建空壳Fragment
private static ListenActivityResultFragment createHolderFragment(FragmentManager fragmentManager) {
ListenActivityResultFragment holder = new ListenActivityResultFragment();
fragmentManager.beginTransaction().add(holder, HOLDER_TAG).commitNowAllowingStateLoss(); // need quickly
return holder;
}
(2)可能会已经存在有一个空壳Fragment
,所以需要加一个查找的逻辑
private static ListenActivityResultFragment findHolderFragment(FragmentManager manager) {
if (manager.isDestroyed()) {
throw new IllegalStateException("Can't access FragmentManager from onDestroy");
}
Fragment fragmentByTag = manager.findFragmentByTag(HOLDER_TAG);
if (fragmentByTag != null && !(fragmentByTag instanceof ListenActivityResultFragment)) {
throw new IllegalStateException("Unexpected fragment instance was returned by HOLDER_TAG");
}
return (ListenActivityResultFragment) fragmentByTag;
}
所以最终调用以上两个方法的方式是:
public static ListenActivityResultRequest holderFragmentFor(FragmentActivity activity) {
return holderFragmentFor(activity.getSupportFragmentManager());
}
public static ListenActivityResultRequest holderFragmentFor(Fragment fragment) {
return holderFragmentFor(fragment.getChildFragmentManager());
}
private static ListenActivityResultFragment holderFragmentFor(FragmentManager fm) {
ListenActivityResultFragment holder = findHolderFragment(fm);
if (holder == null) {
holder = createHolderFragment(fm);
}
return holder;
}
支持Activity
和Fragment
两种情况,先执行查询,找不到再创建空壳Fragment
(3)实现ListenActivityResultRequest
接口
private SparseArray<OnActivityResultCallBack> mCallBackMap = new SparseArray<>();
@Override
public void startActivity(Intent intent, int requestCode, OnActivityResultCallBack callBack) {
mCallBackMap.put(requestCode, callBack);
startActivityForResult(intent, requestCode);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
OnActivityResultCallBack callBack = mCallBackMap.get(requestCode);
if (callBack != null) {
callBack.onActivityResult(resultCode, data);
}
}
这里使用一个字典SparseArray
保存requestCode
对应的OnActivityResultCallBack
,根据实际需求情况,可以任意更改,这里只是举个栗子。
3、暴露给外提供的类
public class ListenActivityProviders {
public static ListenActivityResultRequest listenActivityResult(FragmentActivity activity) {
return ListenActivityResultFragment.holderFragmentFor(activity);
}
public static ListenActivityResultRequest listenActivityResult(Fragment fragment) {
return ListenActivityResultFragment.holderFragmentFor(fragment);
}
}
名字随便取的,见谅见谅~
int requestCode = 1;
Intent intent = new Intent(context, XXActivity.class);
ListenActivityProviders.listenActivityResult(activity).startActivity(intent, requestCode, new OnActivityResultCallBack() {
public void onActivityResult(int resultCode, Intent data) {
// to handle result....
}
});
可能需求逻辑会比较复杂,可能需要连续的处理,为了避免各种异步接口带了的“回调地狱”,我们可能可以在这里将接口改成Rxjava
的Observable
。
在以上实现的基础上,在ListenActivityResultRequest
增加一个返回Observable
的方法。
Observable<ActivityResult> startActivity(Intent intent, int requestCode);
class ActivityResult {
public final int resultCode;
public final Intent data;
ActivityResult(int resultCode, Intent data) {
this.resultCode = resultCode;
this.data = data;
}
}
然后在空壳Fragment
中实现:
@Override
public Observable<ActivityResult> startActivity(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode);
return Observable.create(emitter -> mCallBackMap.put(requestCode, new OnActivityResultCallBack() {
@Override
public void onActivityResult(int resultCode, Intent data) {
emitter.onNext(new ActivityResult(resultCode, data));
emitter.onComplete();
}
}));
}
同理,对于Android处理运行时权限,也可同样适用这样的思路。
最终使用的方法:
Activity that = this; // or fragment
String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; // permissions
KPermission.of(that).requestPermissions(permissions, new IPermissionRequest.IPermissionCallback() { // request
@Override
public void onResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { // callback
StringBuilder stringBuilder = new StringBuilder("onResult\n");
for (int i = 0; i < permissions.length; i++) {
stringBuilder.append(permissions[i].replaceFirst("android.permission.", ""))
.append(" is ")
.append(grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied");
}
Log.d("KPermission", stringBuilder.toString());
Toast.makeText(getApplicationContext(), stringBuilder.toString(), Toast.LENGTH_SHORT).show();
}
});
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。