Android requestCode的限制
一、 why ?
由于才疏学浅,在开发中requestCode的让我很困惑。困惑是因为什么呢,是因为弄混了。要想弄明白,不困惑,来想一想用到requestCode的地方:
① startActivityForResult开启另一个Activity的时候:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
② 请求权限的时候:
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
if (mHasCurrentPermissionsRequest) {
Log.w(TAG, "Can reqeust only one set of permissions at a time");
// Dispatch the callback with empty arrays which means a cancellation.
onRequestPermissionsResult(requestCode, new String[0], new int[0]);
return;
}
Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
mHasCurrentPermissionsRequest = true;
}
(1)首先来看startActivityForResult()的requestCode:
通过查看源码发现:在Activity中startActivityForResult() 和Activity的子类FragmentActivity中的startActivityForResult()是不一样的,代码展示区别:
/** |
/** /** |
通过以上代码的比较我们知道,会造成下面的错误,是FragmentActivity添加的限制,而Activity中没有该限制,这里解决了一点点疑惑:
java.lang.IllegalArgumentException: Can only use lower bits for requestCode
所以这里总结一下:在startActivityForResult()中的resquestCode的限制是 0 <= requestCode <= 216 ,小于零会造成什么问题,你可以试试,我没有尝试。
(2)再来看ActivityCompat请求权限中的requestCode:
public static void requestPermissions(final @NonNull Activity activity,
final @NonNull String[] permissions, final int requestCode) {
if (Build.VERSION.SDK_INT >= 23) {
ActivityCompatApi23.requestPermissions(activity, permissions, requestCode);
} else if (activity instanceof OnRequestPermissionsResultCallback) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
final int[] grantResults = new int[permissions.length]; PackageManager packageManager = activity.getPackageManager();
String packageName = activity.getPackageName(); final int permissionCount = permissions.length;
for (int i = 0; i < permissionCount; i++) {
grantResults[i] = packageManager.checkPermission(
permissions[i], packageName);
} ((OnRequestPermissionsResultCallback) activity).onRequestPermissionsResult(
requestCode, permissions, grantResults);
}
});
}
}
由源码可以知道:当sdk >=23的时候,会走 ActivityCompatApi23.requestPermissions(activity, permissions, requestCode),来看看它干了什么:
public static void requestPermissions(Activity activity, String[] permissions,
int requestCode) {
if (activity instanceof RequestPermissionsRequestCodeValidator) {
((RequestPermissionsRequestCodeValidator) activity)
.validateRequestPermissionsRequestCode(requestCode);
}
activity.requestPermissions(permissions, requestCode);
}
如果Activity实现了接口RequestPermissionsRequestCodeValidator 就会对requestCode进行判断,天啊,终于说到它了。validateRequestPermissionsRequestCode 见名之意,它对requestCode作了限制,看看FragmentActivity实现的该接口是怎么限制的:checkForValidRequestCode() 这个方法是不是很熟悉:上面就有看看吧,看来限制是一样的: 请求权限 requestCode <= 216
@Override
public final void validateRequestPermissionsRequestCode(int requestCode) {
// We use 16 bits of the request code to encode the fragment id when
// requesting permissions from a fragment. Hence, requestPermissions()
// should validate the code against that but we cannot override it as
// we can not then call super and also the ActivityCompat would call
// back to this override. To handle this we use dependency inversion
// where we are the validator of request codes when requesting
// permissions in ActivityCompat.
if (!mRequestedPermissionsFromFragment
&& requestCode != -1) {
checkForValidRequestCode(requestCode);
}
}
你会不会以为这个限制只有在sdk >=23以上才有,那就错了。我们来看看小于23时的分支会直接走到onRequestPermissionsResult(),来看看它:哇,同样的限制。
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
int index = (requestCode >> 16) & 0xffff;
if (index != 0) {
index--; String who = mPendingFragmentActivityResults.get(index);
mPendingFragmentActivityResults.remove(index);
if (who == null) {
Log.w(TAG, "Activity result delivered for unknown Fragment.");
return;
}
Fragment frag = mFragments.findFragmentByWho(who);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for who: " + who);
} else {
frag.onRequestPermissionsResult(requestCode & 0xffff, permissions, grantResults);
}
}
}
二、总结:
FragmentActivity是对Activtiy的一层包装,requestCode的限制是在它里面添加的,而Activity本身对requestCode是没有限制的。所以如果发现有的requestCode大于216仍然能通过,不要疑惑,你懂得!
Android requestCode的限制的更多相关文章
- Android requestcode resultcode的作用
requestcode 一个页面的不同事件,激发不同的函数,startActivityForResult中传入不同的请求码的值以调用下一个界面,在被调用界面结束返回第一个界面时,请求码会自动返回(自动 ...
- android startActivityForResult(Intent intent, int requestCode) 整理与总结! .
假设有两个Activity,主界面A,功能界面B,由A启动B,并传数据给B,B在经过处理后把数据传回给A. 先是A传B: Bundle bundle = new Bundle();bundle.put ...
- Android FragmentActivity 嵌套 Fragment 调用startActivityForResult返回的requestCode错误
Android FragmentActivity 嵌套 Fragment 调用startActivityForResult返回的requestCode错误 此时,要在调用startActivityFo ...
- android小知识之fragment中调用startActivityForResult(Intent intent,int requestcode)所遇到的问题
大家都知道对于Activity和Fragment都可以注册OnActivityResult()方法,但是要注意几点: a.当activity和fragment都注册了OnActivityResult( ...
- Android开发 Fragment中调用startActivityForResult返回错误的requestCode
返回错误的requestCode返回值为65537,在Fragment里调用startActivityForResult,就必须在Fragment里处理onActivityResult.
- Android onActivityResult 设置requestCode 返回的code不对
今天在项目里用到 Intent intent=new Intent(getActivity(), Test.class);startActivityForResult(intent, 1); onAc ...
- Android 6.0 权限知识学习笔记
最近在项目上因为6.0运行时权限吃了亏,发现之前对运行时权限的理解不足,决定回炉重造,重新学习一下Android Permission. 进入正题: Android权限 在Android系统中,权限分 ...
- Android权限管理之Android 6.0运行时权限及解决办法
前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
随机推荐
- 虚拟机下Linux系统如何设置IP地址
虚拟机下Linux系统设置IP地址三种方法 文章来源:https://jingyan.baidu.com/article/ea24bc399ffeb9da62b3318f.html 工具/原料 V ...
- select2 AJAX获取数据
页面效果: index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"& ...
- django图书管理系统实例
首页,其他页面全部继承首页的上半部分 点击发布图书页面 首页点击书名,跳转到图书信息界面,该界面可删除图书 项目结构 #views.py from django.shortcuts import re ...
- JS使用onscroll、scrollTop实现图片懒加载
今天做到项目中的图片展示,由于每一页的图片数量都很多,因此需要为图片的展示设计一种懒加载的功能. 第一要做的当然就是给程序添加滚动监听事件. //触发拉取图片开关,保证正在拉取时不能再次触发 var ...
- ng-model绑定的是ng-option中的什么?
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
- Python常用库之Pilow
基本用法 静态方法 PIL.Image.open(fp, mode=’r’) 传入文件路径(str),返回一个image对象 PIL.Image.alpha_composite(im1, im2) 混 ...
- Manjaro 安装与配置
1.系统安装 Win下使用usbWriter制作安装盘,Manjaro下使用自带的SUSE Studio Imangewriter. 2.初始化配置 2.1.换源,装aurman yaourt虽然已经 ...
- Many Website Of WallPaper
我在这里给大家推荐几个不错的壁纸网站 毕竟一张赏心悦目的壁纸能让你的工作效率提高不少 注意前方高能 一大波网站即将来袭 一系列 如你所见 alphacoders wallpaperdj Wallhav ...
- AGC006D Median Pyramid Hard
闲扯 今天模拟的题,应该是挺简单的二分和贪心,就是没想出来,我好弱啊 顺便ORZ聚聚BLUESKY007,踩爆我了 思路 今天发现中位数性质如此优秀 二分最后塔顶的数,大于等于它的数变为1,小于它的数 ...
- (转)Understanding Memory in Deep Learning Systems: The Neuroscience, Psychology and Technology Perspectives
Understanding Memory in Deep Learning Systems: The Neuroscience, Psychology and Technology Perspecti ...