带你封装自己的『权限治理』框架

前言

本文已经收录到我的 Github 小我私家博客,迎接大佬们惠临寒舍:

我的 Github 博客

本篇文章需要已经具备的知识:

  • Git
    Github 的基本使用
  • Kotlin 语法基础
  • Android 开发基础

学习清单:

  • 若何封装自己的权限框架
  • 将开源库公布到
    JitPack 堆栈的一整套流程

一.为什么要封装这套框架

我们在一样平常开发中,经常需要用到申请运行时权限的知识,于是,经常就写了下面的一大串代码


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

 ...
    //申请 CALL_PHONE 权限
    if (ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.CALL_PHONE
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CALL_PHONE), 1)
    } else {
        call()
    }
}


override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
)
 {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when (requestCode) {
        1 -> {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                call()
            } else {
                Toast.makeText(this"You denied the permission", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

麻鸭,头疼,这么多代码,不仅写着难受,看着更是头疼

带你封装自己的『权限治理』框架 头疼

这时刻,若是这个天下简朴点,纯粹点,就好了

XPermission.request(
    this,
    Manifest.permission.CALL_PHONE
) { allGranted, deniedList ->
    if (allGranted) {
        call()
    } else {
        Toast.makeText(this"You denied $deniedList", Toast.LENGTH_SHORT).show()
    }
}

是不是感受天下又友好了许多呢?这段代码比之前的代码量少了许多不说,逻辑更是清晰了许多鸭!

带你封装自己的『权限治理』框架 滚来了

很显然,上面用到了自己封装的框架,有可能你会一脸不屑:『这算啥?Github 上一堆权限申请框架,他们写的这个简练又漂亮,功效又多又全,超帅的』

我想说:『是的,你说的对,虽然 Github 上有这么多,跑得又快又棒的轮子,然则,别人做的菜总归没有自己的香鸭!我们可以通过自己封装一个简朴的权限申请框架最先,学习公布开源库到 Jitpack / Jcenter 的一整套流程,从而引发自己的学习兴趣,以后自己也多多造轮子(xia zhe teng)!成为 Android 界的轮子哥』

先为大佬送上笔者已经封装好的轮子:https://github.com/LoveLifeEveryday/XPermissions

带你封装自己的『权限治理』框架 XPermission
带你封装自己的『权限治理』框架 上车

二.入坑之路

2.1 建立 Android 项目

新建一个空的 Android 项目

带你封装自己的『权限治理』框架 建立项目

2.2 建立 Github 项目

带你封装自己的『权限治理』框架 建库

  • 然后,把该项目 clone 到一个上面已经建立的 Android 项目的位置

  • 将克隆下来的所有文件所有复制到上一层目录(注重:复制的时刻不要遗忘复制 .git 文件)

  • 将克隆的 XPermission 目录删除

  • 执行一系列的 git add . git commit -m "First commit" git push origin master 操作

2.3 实现 XPermission

  1. 对着最顶层的
    XPermission ,新建一个
    module ,选择
    Android Library

带你封装自己的『权限治理』框架 新建 module

看到 library 就行,如下

带你封装自己的『权限治理』框架 新建 library 乐成

然后,我们思索下,运行时权限的实现思绪,有以下三种:

  • 将运行时权限的操作封装到
    BaseActivity
  • 提供一个透明的
    Activity 来处置
  • 提供一个隐藏的
    Fragment 来处置

本文,将凭据最后一个思绪举行实现

2.3.1 建立 InvisibleFragment

//给  (Boolean, List<String>) -> Unit 指定一个别名
typealias PermissionCallback = (Boolean, List<String>) -> Unit

class InvisibleFragment : Fragment() {

    //界说一个 callback 作为运行时权限申请效果的回调通知方式
    private var callback: PermissionCallback? = null
    
    //界说申请权限的方式,vararg 示意可变长度的 permissions 参数列表
    fun requestNow(cb: PermissionCallbackvararg permission: String) {
        callback = cb
        requestPermissions(permission, 1)
    }

    /**
     * 请求返回效果
     * @param requestCode Int 请求码
     * @param permissions Array<String> 权限
     * @param grantResults IntArray 请求效果
     */

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    )
 {
        if (requestCode == 1) {
            // deniedList 用来纪录被用户拒绝的权限
            val deniedList = ArrayList<String>()
            for ((index, result) in grantResults.withIndex()) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    deniedList.add(permissions[index])
                }
            }
            // allGranted 用来标识是否所有申请的权限都已经授权
            val allGranted = deniedList.isEmpty()
            //对申请权限的效果举行回调
            callback?.let { it(allGranted, deniedList) }
        }
    }
}
  • 首先,我们界说一个
    callback 作为运行时权限申请效果的回调通知方式
  • 然后,界说一个
    requestNow 方式
  • 最后重写
    onRequestPermissionsResult 方式

带你封装自己的『权限治理』框架 第一大步

2.3.2 建立 XPermission

object XPermission {
    private const val TAG = "InvisibleFragment"
    fun request(
        activity: FragmentActivity,
        vararg permission: String,
        callback: PermissionCallback
    )
 {
        val fragmentManager = activity.supportFragmentManager
        val existedFragment = fragmentManager.findFragmentByTag(TAG)
        val fragment = if (existedFragment != null) {
            existedFragment as InvisibleFragment
        } else {
            val invisibleFragment = InvisibleFragment()
            fragmentManager.beginTransaction().add(invisibleFragment, TAG).commitNow()
            invisibleFragment
        }
        //这里在 permission 前面加个星号的意思是:将数组转化为可变长度参数通报已往
        fragment.requestNow(callback, *permission)
    }
}

信赖代码人人都看得懂,以是笔者就不写许多注释了(实在是因为懒..)

2.4 测试

app\build.gradle 中引入 library

[Java网络安全系列面试题] GET 和 POST 的区别在哪里?

dependencies {
    implementation fileTree(dir: 'libs'include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    //添加这行就行
    implementation project(':library')
}

然后举行你喜欢的权限申请

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        makeCallBtn.setOnClickListener {
            XPermission.request(this, Manifest.permission.CALL_PHONE) { allGranted, deniedList ->
                if (allGranted) {
                    call()
                } else {
                    Toast.makeText(this"You  Denied $deniedList", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun call() {
        val intent = Intent(Intent.ACTION_CALL)
        intent.data = Uri.parse("tel:10086")
        startActivity(intent)
    }
}

若是可以的话,恭喜你,你已经乐成一大步了

2.5 公布到 JitPack

2.5.1 JitPack 简介

JitPack 是一个网站,它允许你把 git 托管的 javaandroid 项目(貌似现在仅支持github和码云),轻松公布到 jitpackmaven 堆栈上,它所有内容都通过内容分发网络(CDN)使用加密 https 毗邻获取

2.5.2 为什么用 JitPack

优点:打包比较简朴,省时间,背靠 Github 这座大山

瑕玷:每次导入库的时刻,都要先在根的 build.gradle 文件中添加 maven

带你封装自己的『权限治理』框架 添加 maven

2.5.3 步骤

  • 在根的
    build.gradle 中添加
    maven 插件

点击查看最新版本

buildscript {
    ext.kotlin_version = '1.3.71'
    repositories {
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        //添加 maven 插件
        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

  • library目录的
    build.gradle
    apply 插件和添加
    group
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
//添加下面两行
apply plugin: 'com.github.dcendents.android-maven'
//这里 LoveLifeEveryday 改为你的 github 账号名,我的是:LoveLifeEveryday
group='com.github.LoveLifeEveryday'
android {
...
}
  • 同步一下

带你封装自己的『权限治理』框架 同步

  • 在下令行中输入
    gradlew install ,从而构建你的
    library 到你的内陆
    maven 堆栈

带你封装自己的『权限治理』框架 gradlew install

守候 BUILD SUCCESSFUL,BUILD FAIL,说明构建失败,这时刻你就要根据失败提醒去排错,排错完后在执行一遍 gradlew install 下令,直到泛起 BUILD SUCCESS

  • 把代码提交到内陆
    git 堆栈

git add .git commit -m “XX”

  • 在内陆
    git 堆栈打
    tag
git tag -a 1.0.0 -m "第一版"
git push origin 1.0.0
  • 打开你的
    libary
    github 界面,点击
    release,如下:

带你封装自己的『权限治理』框架 release

  • 点击
    Draft a new release,新建一个
    release,如下:

带你封装自己的『权限治理』框架 image-20200424182958983

  • 然后填信息,如下:

带你封装自己的『权限治理』框架 填信息

  • 填好信息后,点击
    publich release,如下:

带你封装自己的『权限治理』框架


  • GitHub 账号上岸、注册
    jitpack
  • 上岸后,在地址栏中输入你的
    library
    github 项目地址,然后点击
    Look Up ,如下:

带你封装自己的『权限治理』框架

  • 然后点击
    Get it,它会滚到下面去,你要滚回上面去,先等一会,等
    jitpack 那里构建完,会泛起一个绿色的
    log,则构建乐成,如下:

带你封装自己的『权限治理』框架

然后你就可以愉快的在项目中根据它的提醒引用你的开源库

带你封装自己的『权限治理』框架

  • 点击谁人
    jitpack ,把它的链接复制到你的
    Readme 中去,如下:

带你封装自己的『权限治理』框架 jitpack

2.6 实验使用你的框架

当然是在 app\build.gradle

//引用自己的开源库
implementation 'com.github.LoveLifeEveryday:XPermissions:1.0.0'

然后实验使用吧

带你封装自己的『权限治理』框架 完成

2.7 美化你的项目

一个优异的开源项目,readme 一定不会差

鲁迅说:『虽然这些事情不会让你的项目变得牛逼,但会让你的项目变得漂亮,方便了其他人去领会你这个项目』

详细的美化操作,可以参考这篇文章:若何让你的 GitHub 项目表面上更专业

带你封装自己的『权限治理』框架 悦目

三.我在使用中遇到的问题

3.1 在模拟器上 Call 权限申请无反映

  • 发生情景:在
    逍遥模拟器上测试
    Call 权限

至于我为什么要使用逍遥模拟器,这又是另一个故事了

  • 解决:真机测试正常申请权限,于是百度了一波,发现许多模拟器没有
    Call 这个权限(such as 夜神模拟器),我以为原装的模拟器应该是可以正常运行的
  • 结论:模拟器的锅

3.2 上传到 JcenterFailed

  • 发生情景:执行上传下令的时刻,运行到最后发生错误
  • 错误:
* What went wrong:
Execution failed for task ':utils:bintrayUpload'.
> org.apache.http.NoHttpResponseException: The target server failed to respond
  • 历程:
    Google &&
    Baidu
  • 结论:网络问题
  • 效果:实验了通俗网络和 Ke Xue 上网,照样无法解决,转为使用
    JitPack

若是想领会,怎么上传到 Jcenter 的话,可以看下这篇文章:AS上传Library到JCenter 教程+踩坑纪录

带你封装自己的『权限治理』框架 bug 退散

若是文章对您有一点辅助的话,希望您能点一下赞,您的点赞,是我前进的动力

本文参考链接:

本文使用 mdnice 排版

原创文章,作者:28x29新闻网,如若转载,请注明出处:https://www.28x29.com/archives/5994.html