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 文中如有纰 ...
随机推荐
- 2017第十三届湖南省省赛A - Seating Arrangement CSU - 1997
Mr. Teacher老师班上一共有n个同学,编号为1到n. 在上课的时候Mr. Teacher要求同学们从左至右按1, 2, …, n的顺序坐成一排,这样每个同学的位置是固定的,谁没来上课就一目了然 ...
- Kattis之旅——Chinese Remainder
Input The first line of input consists of an integers T where 1≤T≤1000, the number of test cases. Th ...
- foreve结束
import asyncio from threading import Thread import time print('main start:',time.time()) async def s ...
- Centos7.3+uwsgi+Nginx部署Django程序
1. 安装Python,这里我用的是阿里云的centos7.3,自带python2,所以,此步略过,具体安装Python可Google. 2. 安装uwsgi,如果安装失败的话首先,我的Python解 ...
- P2590 [ZJOI2008]树的统计(树链剖分)
P2590 [ZJOI2008]树的统计 虽然是入门树剖模板 但是我终于1A了(大哭) 懒得写啥了(逃 #include<iostream> #include<cstdio> ...
- ionic + angular + cordova, 打造专属自己的App!
ionic 学习地址:http://ionicframework.com/ ionic 好处: ionic serve --lab 预览平台间的差异化 sass 提 ...
- 我是这样做APP的:击中用户的痛点(转)
击中用户的痛点 点评,感觉取名叫做“用户痛点的取舍”更加合适.很多公司.项目的失败完全取决于决策人取舍的失败,一味地追求大而全.迎合上级领导,专断而没有和团队做客观的分析.本文虽然以一个应该来说并不复 ...
- Tree Implementation with Python
Tree Implementation with Python List of List 代码如下: def binary_tree(val): return [val, [], []] def in ...
- java常用类-String类
* 字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. * 通过查看API,我们可以知道 * A:字符串字面值"abc"也可以看成是一个字符串对象. * B:字符串是 ...
- web site optimization
@ 如果有很多图片(比如web服务器的页面上有多个小图片),通常是没有必要记录文件的访问时间的,这样就可以减少写磁盘的I/O,这个要如何配置 @ 首先,修改文件系统的配置文件/etc/fstab ,然 ...