大胸弟 requestCode还在困扰你嘛

2024-02-20 23:10
文章标签 困扰 requestcode 胸弟

本文主要是介绍大胸弟 requestCode还在困扰你嘛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

开发中遇到的问题

呀哟 大胸弟

界面传值

在开发中,当在一个A界面(Activity)中打开B界面(Activity),如果想要B->A传值的情况有很多。但是这种所有获取到的结果都需要到onActivityResult中处理的方式实在令人蛋疼。

15697582283234

界面 A

int mRequestCode = xxx;//定义 requestCode 
context.startActivityForResult(intent, requestCode);@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if(requestCode == mRequestCode){ //判断 requestCode//执行}
}

界面 B

Intent intent = Intent()
intent.putExtra("text",text.text.toString())
setResult(Activity.RESULT_OK,intent)
finish();

打开相册

要写如下的代码,先要权限检查,又要监听界面的回调。

private final static int REQUEST_CODE = 100;
private final static int PERMISSION_REQUEST_CODE = 200;//打开相册
private void openPic(){//1.检查权限,并请求权限checkPermission();
}private void checkPermission(){//首先进行权限判断,和请求//先  check//然后 requestPermissions...
}//处理权限
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);//判断请求码if(requestCode==PERMISSION_REQUEST_CODE){if(有权限){//在拥有权限的情况下:打开系统的选择图片界面Intent intentToPickPic = new Intent(Intent.ACTION_PICK, null);intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg");startActivityForResult(intentToPickPic, REQUEST_CODE);}}
}//当拍摄照片完成时会回调到onActivityResult 在这里处理照片的裁剪或其他的操作
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode == RESULT_OK) {switch (requestCode) {case REQUEST_CODE: {//处理图片逻辑...break;}}}super.onActivityResult(requestCode, resultCode, data);
}

还有一些判断等等,写起来特别麻烦。需要自己定义requestCode,然后重写onRequestPermissionsResult 和 onActivityResult 方法,然后在处理一堆逻辑!

风好大我好冷

试想一下,我们敲着代码唱着歌。突然,半路上跳出一群马匪,让我们到另一个页面获取一点数据,获取后还不让在当前代码位置处理逻辑,要去onActivityResult添加一个requestCode分支处理结果,处理完才让回来,等这一切都做完回来难免就会陷入这样的思考:我是谁,我在哪,我在干什么,我刚才写到哪了……

那么有没有一种解决方法呢?

终极解决方案 AvoidOnResultHelper

我们先来看看怎么使用,然后在讲解原理!

使用方法

在子项目中的 build.gradle 文件中添加

dependencies {implementation 'vip.ruoyun.helper:avoid-onresult-helper:1.0.3'
}

开启 Activity

Intent intent = new Intent();
AvoidOnResultHelper.startActivityForResult(this, intent, new AvoidOnResultHelper.ActivityCallback() {@Overridepublic void onActivityResult(int resultCode, Intent data) {//处理操作}
});

请求权限

String[] permissions = {};
AvoidOnResultHelper.requestPermissions(this, permissions, new AvoidOnResultHelper.PermissionsCallBack() {@Overridepublic void onRequestPermissionsResult(@NonNull String[] permissions, @NonNull int[] grantResults) {//处理逻辑}
});

介绍到此处是不是感觉减少了好多代码?连requestCode 都不需要定义!~~

框架内部定义好了连requestCode,如果在开发中感觉和现有的 requestcode 冲突的话,可以设置 RequestCodeRange 范围,轻松解决问题,设置代码如下:

AvoidOnResultHelper.setRequestCodeRange(65000, 65535);

除了上面这些功能外,还有那些好用的功能?

可以监听当前 activity 的生命周期.

public interface LifecycleListener {void onStart();//开始void onStop();//结束void onDestroy();//销毁
}

LifecycleListenerWrapper 是此接口的空实现.

//添加监听事件
LifecycleListener lifecycleListener = new LifecycleListener.LifecycleListenerWrapper() {@Overridepublic void onStart() {}
};
//添加监听事件
AvoidOnResultHelper.addLifecycleListener(this, lifecycleListener);//粘性通知,当第一次添加的时候,就执行相应的回调方法
AvoidOnResultHelper.addLifecycleListener(this, lifecycleListener, true);

可选操作

//移除监听事件,默认可以不用移除lifecycleListener,除非在当前界面存在时候,想要不让某些类监听,那么可以手动进行移除(removeLifecycleListener)
AvoidOnResultHelper.removeLifecycleListener(this, lifecycleListener);

源码地址

https://github.com/bugyun/AvoidOnResultHelper

看到此处,是不是感觉不过瘾?原理讲解来了~~

大家都停下,听我说我要开始装逼了

原理

我们先来分下一下 FragmentActivity 的源码,在 onStart、onStop、onPause、onActivityResult、onRequestPermissionsResult等方法的时候,都会执行FragmentManagerImpl mFragments 对象的dispatchCreate、dispatchStart、dispatchStop方法,还会执行对应 fragment 的onActivityResult和onRequestPermissionsResult方法。

final FragmentManagerImpl mFragments = new FragmentManagerImpl();protected void onCreate(@Nullable Bundle savedInstanceState) {this.mFragments.attachHost((Fragment)null);super.onCreate(savedInstanceState);...//省略不必要的代码this.mFragments.dispatchCreate();
}protected void onStart() {super.onStart();...//省略不必要的代码this.mFragments.noteStateNotSaved();this.mFragments.execPendingActions();this.mFragments.dispatchStart();
}protected void onStop() {super.onStop();...//省略不必要的代码this.mFragments.dispatchStop();
}protected void onPause() {super.onPause();...//省略不必要的代码this.mFragments.dispatchPause();
}protected void onDestroy() {super.onDestroy();...//省略不必要的代码this.mFragments.dispatchDestroy();
}public void onLowMemory() {super.onLowMemory();this.mFragments.dispatchLowMemory();
}protected void onActivityResult(int requestCode, int resultCode, Intent data) {...//省略不必要的代码Fragment targetFragment = mFragments.findFragmentByWho(who);targetFragment.onActivityResult(requestCode & 0xffff, resultCode, data);...//省略不必要的代码
}public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {...//省略不必要的代码final List<Fragment> activeFragments =mFragments.getActiveFragments(new ArrayList<Fragment>(activeFragmentsCount));Fragment frag = activeFragments.get(index);if (frag == null) {Log.w(TAG, "Activity result no fragment exists for index: 0x"+ Integer.toHexString(requestCode));} else {frag.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults);}...//省略不必要的代码}
}

我们在来看 FragmentManagerImpl 的源码,就知道 FragmentActivity 的声明周期方法在执行的时候,都会执行包含的 fragment 的声明周期方法。代码如下:

public void dispatchCreate() {mStateSaved = false;moveToState(Fragment.CREATED, false);
}public void dispatchActivityCreated() {mStateSaved = false;moveToState(Fragment.ACTIVITY_CREATED, false);
}public void dispatchStart() {mStateSaved = false;moveToState(Fragment.STARTED, false);
}void moveToState(int newState, boolean always) {moveToState(newState, 0, 0, always);
}void moveToState(int newState, int transit, int transitStyle, boolean always) {...//省略不必要的代码if (mActive != null) {boolean loadersRunning = false;for (int i=0; i<mActive.size(); i++) {Fragment f = mActive.get(i);if (f != null) {moveToState(f, newState, transit, transitStyle, false);// 执行声明周期方法...//省略不必要的代码}}...//省略不必要的代码}
}void moveToState(Fragment f, int newState, int transit, int transitionStyle,boolean keepActive) {...//省略不必要的代码switch (f.mState) {case Fragment.INITIALIZING:...//省略不必要的代码f.onAttach(mActivity);...//省略不必要的代码if (f.mFromLayout) {...//省略不必要的代码if (f.mView != null) {...//省略不必要的代码f.onViewCreated(f.mView, f.mSavedFragmentState);} else {f.mInnerView = null;}}case Fragment.CREATED:...//省略不必要的代码f.onViewCreated(f.mView, f.mSavedFragmentState);...//省略不必要的代码case Fragment.ACTIVITY_CREATED:case Fragment.STOPPED:...//省略不必要的代码f.performStart();case Fragment.STARTED:...//省略不必要的代码f.performResume();}} else if (f.mState > newState) {switch (f.mState) {case Fragment.RESUMED:...//省略不必要的代码f.performPause();case Fragment.STARTED:f.performStop();case Fragment.STOPPED:f.performReallyStop();case Fragment.ACTIVITY_CREATED:f.performDestroyView();case Fragment.CREATED:...//省略不必要的代码}}f.mState = newState;
}

通过上面的代码,可以看出都会执行moveToState 方法,在moveToState方法中,通过 for 循环执行activity 中所有的 fragment 的生命周期方法。

那么,我们就可以创建一个没有界面的 fragment 添加到 activity 中,就可以完美监听界面的声明周期和回调方法。到此原理讲解结束。

打完收工!

知识拓展

比如我们现在 很多第三方的库,glide 、Android Architecture Component 等等这些库都是使用这些原理。有兴趣的小伙伴可以立马去阅读源码~~

福利

安利下权限库,超级简单好用~

https://github.com/bugyun/MissPermission

慢走不送!

如果你喜欢我的文章,可以关注我的掘金、公众号、博客、简书或者Github!

简书: https://www.jianshu.com/u/a2591ab8eed2

GitHub: https://github.com/bugyun

Blog: https://ruoyun.vip

掘金: https://juejin.im/user/56cbef3b816dfa0059e330a8/posts

CSDN: https://blog.csdn.net/zxloveooo

欢迎关注微信公众号

这篇关于大胸弟 requestCode还在困扰你嘛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/729824

相关文章

【leetcode详解】考试的最大困扰度(滑动窗口典例)

实战总结: sum += answerKey[right] == c; 经典操作,将判断语句转化为0, 1接收来计数//大问题分解: 对'T'还是'F'做修改, 传参为c//滑动窗口: 遍历, 维护left& right指向 及 c的个数, 更新不知从何下手写代码时:考虑先写好第一次的,然后以此为基础补充代码以适后续情况 题面: 解题感受: 思路总体好想, 实现略有挑战。 思路分析:

OpenCV版本问题带来的困扰

最近一直在用一些函数,突然发现有一些函数前面带cv,有的函数没有带,到底这二者有什么区别。 如cvThreshold 和threshold、cvCvtcolor和cvtcolor、CvFindcontous和findcontous 网上对于这个问题的介绍很少,初步查了一下,觉得是版本问题,前面带cv的函数应该是OpenCV1.x版本的,不带cv应该是2.0之后的函数, C版本:

一个困扰了我三天的SQL优化问题。(多条数据取最近的数据)

由于优化的方向不对,一个SQL困扰了我好几天,物化视图什么之类的,全部都试过了,还是没有解决。今天,在看这个问题的时候,灵光一现,咦,好像是这里有问题,然后改了一下,终于解决了。这个SQL,从最初的16秒,后面换了各种方法,有180秒,150秒,60多秒,试过了各种SQL,终于,优化到了0.3秒。好了,现在说下问题。            这个SQL总共涉及了6张表,其实

浮点数精度不再是困扰:Python高手的精准编程秘籍!解决Python浮点数精度问题!

本专栏主要是自己在实际使用Python和工作中遇到的一些问题以及解决方法,还有一些是在网上搜集到的一些频繁出现和比较复杂的疑难杂症,目的就是希望帮助到使用Python的小伙伴们,无论是刚入门的新手,还是已经精通的Python高手,希望大家一起加油 🧑‍💻博客主页:长风清留扬-CSDN博客📚系列专栏:Python疑难杂症百科-BUG编年史🤝每天更新大数据相关方面的技术,分享

day-47 考试的最大困扰度

思路 滑动窗口:如果用left和right表示连续相同结果的题数的左右边界,那么意味着可以修改k次,我们可以分别统计T和F连续相同的题数的最大值,然后返回Math.max(maxLen(‘T’,k),maxLen(‘F’,k))即可 解题过程 假设计算连续相同答案为T的题数,用一个变量num记录left和right之间F的个数 num<=k时,right++,num>k时,将left向右移动,

[M滑动窗口] lc2024. 考试的最大困扰度(滑动窗口+问题转换)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接:2024. 考试的最大困扰度 前置题: [M滑动窗口] lc1004. 最大连续1的个数 III(滑动窗口+模板题) 题单: 滑动窗口(定长/不定长/多指针) 二、不定长滑动窗口 §2.1 求最长/最大 2. 题目解析 思路: 简单的问题转换,就变成了 [M滑动窗口] lc1004. 最大连续1

无internet,安全(困扰半天,终于解决)

试过很多方法,网络重置、更改网络适配器、更新网卡驱动等等,都没有解决! 还得是火绒断网修复,简直是赛博华佗,话不多说,解决方案咱直接上图 Microsoft Store 搜索 火绒,点击免费下载 安装完成后,双击火绒安全软件,找到断网修复 最后点击全面检查,即可修复网络问题!!! 如果仍未解决问题,可在评论区留言or私信,我都会努力为你们答疑的。 希望各位客官点点赞,谢谢咯

电脑弹出丢失mfc140.dll有什么解决的办法,七种不同方法教你解决这个困扰

一、mfc140.dll文件的功能与重要性 功能概述 mfc140.dll作为Microsoft Foundation Classes库的核心组件,提供了一系列基础类和应用程序框架,使得开发者可以快速构建具有丰富用户界面的Windows应用程序。这些功能包括但不限于: 用户界面组件:如窗口、按钮和对话框等的创建和管理。 消息映射机制:简化了消息处理流程,使得事件响应更加直观。 控件支持:

告别夏季粉尘螨虫困扰,这些空气净化器品牌你不能错过!

夏季来临,粉尘螨虫肆虐,对家居环境造成巨大威胁。俗话说:“病从口入,祸从口出。”夏季是粉尘和螨虫的活跃期,常规的清洁手段如吸尘、抹布擦拭等已无法彻底清除这些顽固的过敏源。尤其是在空调使用频繁的日子里,空气质量更是令人堪忧。市面上的空气净化器品牌琳琅满目,功能五花八门,消费者往往无所适从。为了让你在购买空气净化器时不再迷茫,作为一名资深家电博主特意筛选了几款值得信赖的品牌,推荐给大家。 灰

理解线程安全:保护你的代码免受并发问题困扰

目录 前言 一、什么是线程安全? 二、为什么需要线程安全? 三、实现线程安全的方法 四、synchronized 使用 synchronized 关键字时,需要注意以下几点: 五、Demo讲解 前言         在现代软件开发中,尤其是在多线程编程中,线程安全(Thread Safety)是一个至关重要但又复杂的话题。本文将从基础概念开始,逐步深入,帮助你理解什么