如何巧妙避免Activity的onActivityResult代码臃肿

本文介绍一种封装方法,通过创建无视图的Fragment对象作为桥梁,简化Activity中onActivityResult的处理流程,提高代码可读性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要讲解Activity的onActivityResult的问题。

记得刚开始开发项目的时候需求一下来时,噼里啪啦直接敲代码,功能实现是没问题了,后期其它同事维护时发现代码非常臃肿,特别当需要修改或添加功能时,涉及到一些特别庞大的对象,立马懵逼了。

页面之间交互、startActivityForResult跳转到系统指定页面 这些是在项目里非常常用的,当页面功能越庞大,那么它的请求和响应也对应的越臃肿,面对一大堆代码时,就会出现在onActivityResult方法里忘记刚刚写的请求码是多少,又得回头看一眼还担心出错的问题,看着onActivityResult里面的各种 if()  else if(),连自己都懵逼了。

废话不多说了,思路是通过一个无视图的Frgament对象作为桥梁,使用它进行请求和响应来避免我们自己的onActivityResult方法等,封装一个BridegResult类,构造BridegResult时创建一个无视图的BridegFragment对象,与Activity绑定生命周期方便同步一些逻辑处理,所有的具体逻辑封装在BridegFragment类里,传递接口进行回调,BridegResult只提供一些调用方法。

本文提供的代码是根据我自己的项目需求封装而成,对权限和数据传递两个部分做了一个封装,只是提供思路供大家参考,如有错误之处请指正!

注释很清晰,代码如下!

public class BridegResult{

    private BridegFragment mBridegFragment;
    private String mTag = "tag";

    public BridegResult(FragmentActivity activity){
        mBridegFragment = getBridegFragment(activity);
    }

    public BridegResult(Fragment fragment){
        mBridegFragment = getBridegFragment(fragment.getActivity());
    }



    //初始化Frgament对象 进行生命周期绑定
    private BridegFragment getBridegFragment(FragmentActivity activity){
        //初始化Fragment时,将它与Activity生命周期进行绑定
        BridegFragment bridegFragment = new BridegFragment();
        FragmentManager manager = activity.getSupportFragmentManager();
        manager.beginTransaction().add(bridegFragment,mTag).commitAllowingStateLoss();
        return bridegFragment;
    }

    //提供跳转方法
    public void startResult(Intent intent, int requestCode, CallbackResult callback){
      mBridegFragment.startResult(intent,requestCode,callback);
    }


    //提供授权方法
    public void requestPermissions(String[] permissions, int requestCode,String content, CallbackPermissi callback) {
        mBridegFragment.requestPermissions(permissions,requestCode,content,callback);
    }
}

具体逻辑如下:

public class BridegFragment extends Fragment {


    private Map<Integer,CallbackResult> mCallbackMap = new HashMap<>();   //结果集合
    private Map<Integer,CallbackPermissi> mCallbackPermissionsMap = new HashMap<>();    //权限集合

    private PopUpWindowPermission mPopUpWindowPermission; //提示窗口

    private static final int PERMISSIONS_FLAG = 88; //授权标识
    private int mCurrentCode;


    private String[] mCurrentPermissions;
    private String mHintContent;




    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == PERMISSIONS_FLAG){    //这是权限回调
            CallbackPermissi callbacks = mCallbackPermissionsMap.remove(mCurrentCode);
            if(null != callbacks){
                //假设用户跳转到系统授权页面,不授权返回,也会执行当前方法,需要二次判断权限
                //mCurrentPermissions   mCurrentCode    就是记录当前的权限
                if(Utils.isPermission(getContext(),mCurrentPermissions)){
                    callbacks.onPermissionSucceed(mCurrentCode);
                }else{
                    callbacks.onPermissionFailed(mCurrentCode);
                }
            }
        }else{  //这是普通的数据回调
            CallbackResult callback = mCallbackMap.remove(requestCode);
            if(null != callback){
                callback.onActivityResult(requestCode,resultCode,data);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //用户同意权限
        if(isPermission(grantResults)){
            CallbackPermissi callback = mCallbackPermissionsMap.remove(requestCode);
            if(null != callback){
                callback.onPermissionSucceed(requestCode);
            }
        }else {
            //用户勾选 不在询问,我们再次请求权限时,会被系统直接默认到当前方法的失败状态,所以要针对性处理这个问题
            //勾选就弹出窗口帮助用户自动跳转到系统授权页面
            if(isPermissionRationale(getActivity(),permissions)){
                showWindow();
            }else{      //没有勾选就提示用户需要授权
                CallbackPermissi callback = mCallbackPermissionsMap.remove(requestCode);
                if(null != callback){
                    callback.onPermissionFailed(requestCode);
                }

            }
        }}



    //判断用户是否设置了某个权限为 不在询问
    private boolean isPermissionRationale(FragmentActivity activitie,String[] permissions){
        boolean flag = false;
        for (int i=0;i<permissions.length;i++){
            if(!ActivityCompat.shouldShowRequestPermissionRationale(activitie,permissions[i])) {
                flag = true;
                break;
            }
        }
            return flag;
    }


    //判断用户是否全部授权了   正常一组权限当中第0个授权,其它默认授权,考虑到调用者传的权限数组不止一组,需要都进行判断
    private boolean isPermission(int[] grantResults){
        boolean flag = true;
        for (int i=0;i<grantResults.length;i++){
            if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
                flag = false;
                break;
            }
        }
       return flag;
    }

    //跳转到页面的授权页面
    private void showWindow() {
        if (null == mPopUpWindowPermission) {
            mPopUpWindowPermission = new PopUpWindowPermission(getActivity(), new PopUpWindowPermission.OnClick() {
                @Override
                public void config() {
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", getContext().getPackageName(), null);
                    intent.setData(uri);
                    startActivityForResult(intent, PERMISSIONS_FLAG);   //PERMISSIONS_FLAG 避免在onActivityResult方法里错乱
                }

                @Override
                public void cancel() {}
            });
        }
        mPopUpWindowPermission.show(mHintContent);
    }

    //进行回调跳转
    public void startResult(Intent intent, int requestCode, CallbackResult callback) {
        mCallbackMap.put(requestCode,callback);
        startActivityForResult(intent,requestCode);
    }


    /**
     *
     * @param permissions   权限
     * @param requestCode   请求码
     * @param content   提示用户文字
     * @param callback  回调
     */
    public void requestPermissions(String[] permissions, int requestCode,String content, CallbackPermissi callback) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(null == permissions || permissions.length <= 0 || null == getContext()){
                return;
            }
            //保存对应的请求码和回调对象
            mCallbackPermissionsMap.put(requestCode,callback);
            mHintContent = content; //窗口提示语
            //当前两个变量是用来处理用户跳转到系统授权页面操作后,返回回时,可能并没有授权,需要二次判断权限
            mCurrentCode = requestCode;
            mCurrentPermissions = permissions;
            //权限都满足的情况下直接回调成功
            if(Utils.isPermission(getContext(),permissions)){
                //操作完成就移除任务
                CallbackPermissi callbacks = mCallbackPermissionsMap.remove(requestCode);
                if(null != callbacks){
                    callbacks.onPermissionSucceed(requestCode);
                }
            }else{  //不满足情况下 直接申请权限
                requestPermissions(permissions,requestCode);
            }
        }else{      //低于6.0直接回调成功
            callback.onPermissionSucceed(requestCode);
        }
    }
}




提供两个接口,一个是权限回调,一个是数据回调

public interface CallbackPermissi {

    void onPermissionSucceed(int requestCode);
    void onPermissionFailed(int requestCode);
}
public interface CallbackResult {

    public void onActivityResult(int requestCode, int resultCode, Intent data);
}

提供用户是否授权的窗口

public class PopUpWindowPermission implements View.OnClickListener {

    private PopupWindow mPopupWindow;

    private OnClick mOnClick;
    private FragmentActivity mActivity;
    private TextView mContentTv;

    public PopUpWindowPermission(FragmentActivity activity, OnClick click){
        mOnClick = click;
        mActivity = activity;
        initView(activity);

    }

    private void initView(FragmentActivity activity) {
        View inflate = LayoutInflater.from(activity).inflate(R.layout.pop_permission, null);
        inflate.findViewById(R.id.config_btn).setOnClickListener(this);
        inflate.findViewById(R.id.cancel_btn).setOnClickListener(this);
        mContentTv = (TextView) inflate.findViewById(R.id.msg_tv);
        mPopupWindow = new PopupWindow(inflate, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
        mPopupWindow.setOutsideTouchable(true);
        mPopupWindow.setFocusable(true);
    }


    public void show(String content){
        mContentTv.setText(content);
        mPopupWindow.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
    }


    public void dismiss(){
        mPopupWindow.dismiss();
    }
    @Override
    public void onClick(View view) {
        if(view.getId() == R.id.config_btn){
            mOnClick.config();
        }else{
            mOnClick.cancel();
        }
        dismiss();
    }


    public interface OnClick{
        void config();
        void cancel();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值