首页| 论坛| 搜索| 消息
主题:国内第三方Rom在Android6.0以下系统的权限适配
z3960发表于 2025-07-18 10:18
terKnife的实现方式。

基于APT与注解,编译过程中生成代码,自动添加回调

1、基于APT,定义一系列Annotation,并动态生成辅助Listener类2、添加Android支持库,在基类统一处理回调,3、添加工具类,连接绑定Listener与Activity(Fragment)
相应的实现分三个库:注解库APT生成支持库Android支持库

注解库:




注解库
主要用来定义一些回调方法注解、及请求实体的类注解

代码语言:javascript代码运行次数:0
运行
AI代码解释
* ActivityPermission* FragmentPermission* OnDenied* OnGranted* OnGrantedListener* OnNeverAsk* OnShowRationale

APT生成支持库


主要用来在编译阶段,动态生Listener类

代码语言:javascript代码运行次数:0
运行
AI代码解释
PermissionProcessor.java
部分参考代码:

代码语言:javascript代码运行次数:0
运行
AI代码解释
@AutoService(Processor.class)public class PermissionProcessor extends AbstractProcessor {private Elements elementUtils;private Set getSupportedAnnotations() {Set annotations = new LinkedHashSet();annotations.add(OnDenied.class);annotations.add(OnGranted.class);annotations.add(OnNeverAsk.class);annotations.add(OnShowRationale.class);return annotations;}@Overridepublic synchronized void init(ProcessingEnvironment env) {super.init(env);elementUtils = env.getElementUtils();}@Overridepublic boolean process(Set annotations, RoundEnvironment roundEnv) {if (!checkIntegrity(roundEnv))return false;Set elementActivities = roundEnv.getElementsAnnotatedWith(ActivityPermission.class);Set elementFragments = roundEnv.getElementsAnnotatedWith(FragmentPermission.class);return makeListenerJavaFile(elementActivities) && makeListenerJavaFile(elementFragments);}...

Android支持库


主要会封装了一些工具类,基类以及对回调的处理

代码语言:javascript代码运行次数:0
运行
AI代码解释
* BasePermissionCompatActivity.java* BasePermissionCompatFragment.java* PermissionCompat.java* PermissionUtils.java
参考代码:

代码语言:javascript代码运行次数:0
运行
AI代码解释
public class PermissionCompat {private static int sNextRequestCode;static final Map BINDERS = new LinkedHashMap();// 分批次请求权限public static void requestPermission(BasePermissionCompatActivity target, String[] permissions) {Class targetClass = target.getClass();try {// 找到监听Listener类,并实例一个OnGrantedListener listener = findOnGrantedListenerForClass(targetClass, permissions);if (PermissionUtils.hasSelfPermissions(target, permissions)) {listener.onGranted(target, permissions);} else if (PermissionUtils.shouldShowRequestPermissionRationale(target, permissions)) {// 拒绝过,再次请求的时候,这个函数是否有必要,不在询问后,返回false,第一次返回false,//listener.onShowRationale(target, permissions);startRequest(target, listener, permissions);} else {startRequest(target, listener, permissions);}} catch (Exception e) {throw new RuntimeException("Unable to bind views for " + targetClass.getName(), e);}}private static void startRequest(BasePermissionCompatActivity target, OnGrantedListener listener, final @NonNull String[] permissions) {target.setOnGrantedListener(listener);ActivityCompat.requestPermissions(target, permissions, getNextRequestCode());}

使用

1、Activity继承BasePermissionCompatActivity2、用注解写回调函数,支持权限分组,跟单独处理,但是每个分组都要写自己的回调函数(目前回调函数,不支持参数)3、回调必需配套,也就是一个权限必须对应四个函数,否则编译不通过4、请求的权限必须有回调函数,不然报运行时错误--崩溃@ActivityPermission public class PermssionActivity extends BasePermissionCompatActivity {。。。 @OnGranted(value = {Manifest.permission.CAMERA}) void granted() { LogUtils.v("granted"); }@OnDenied(value = {Manifest.permission.CAMERA}) void onDenied() { LogUtils.v("onDenied"); }@OnNeverAsk(value = {Manifest.permission.CAMERA}) void OnNeverAsk() { LogUtils.v("OnNeverAsk");} @OnShowRationale(value = {Manifest.permission.CAMERA}) void OnShowRationale() { LogUtils.v("OnShowRationale"); } @OnClick(R.id.get) void get() { PermissionCompat.requestPermission(this, new String[]{Manifest.permission.CAMERA}); } }

国产ROM兼容性


6.0之前权限管理即不是原生功能又没有制定相应标准,每个厂家的实现都是完全不同的,虽然4.3 Google官方试图推出AppOpsManager来动态适配权限管理,但由于不成熟,一直到6.0也没走向前台。不过,看6.0之前国内ROM的表现,基本是在每个服务内部触发鉴权请求,对原生权限的判断并没多大影响,所以兼容没太大问题。
下一页上一页  (2/3)
回帖(5):
5 # huwg
07-19 00:31
谢谢分享
4 # huwg
07-19 00:31
来看看了
3 # srwam
07-18 22:30
了解一下
2 # srwam
07-18 22:30
来看看
1 # 爱我中华
07-18 12:41
多谢分享

全部回帖(5)»
最新回帖
收藏本帖
发新帖