第一行代码第三版实践与资源分享

这里简单记录下,第一行代码第三版最后一章的实践。

实现 PermissionX 开源库

对运行时权限的 API 封装并不是一件容易的事,因为这个操作是有特定的上下文依赖的。一般需要在 Activity 中接收 onRequestPermissionsResult() 方法的回调才行,所以不能那个简单地将整个操作封装到一个独立的类中。

受此限制,也衍生出了一些特别的解决方案,比如将运行时权限的操作封装到 BaseActivity 中,或者提供一个透明的 Activity 来处理运行时权限等。

Google 在 Fragment 中提供了相同的 API,使得在 Fragment 也能申请运行时权限。Fragment 并不必须有界面,所以可以向 Activity 中添加一个隐藏的 Fragment,在这个隐藏的 Fragment 中对运行时权限 API 封装。

typealias PermissionCallback = (Boolean, List<String>) -> Unit

class InvisibleFragment : Fragment() {

    private var callback: PermissionCallback? = null

    fun requestNow(cb: PermissionCallback, vararg permissions: String) {
        callback = cb
        requestPermissions(permissions, 1)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        if (requestCode == 1) {
            val deniedList = ArrayList<String>()
            for ((index, result) in grantResults.withIndex()) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    deniedList.add(permissions[index])
                }
            }
            val allGranted = deniedList.isEmpty()
            callback?.let { it(allGranted, deniedList) }
        }
    }

}

typealias 关键字可以用于给任意类型指定一个别名,从而让代码更加简洁易懂。

InvisibleFragment 中并没有重写 onCreateView() 方法来加载某个布局,因为它自然就是一个不可见的 Fragment,只需要将它添加到 Activity 中即可。

object PermissionX {

    private const val TAG = "InvisibleFragment"

    fun request(
        activity: FragmentActivity,
        vararg permissions: 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
        }
        fragment.requestNow(callback, *permissions)
    }

}

FragmentActivity 是 AppCompatActivity 的父类。

需要注意 permissions 参数在这里实际上是一个数组,对于数组,是不可以直接将它传递给另一个接收可变长参数的方法。* 表示将一个数组转换成可变长参数传递过去,而不是指针的意思。

总结

整体来说,加深了自己对 Kotlin 的理解与运用。电子书分享 👇
第一行代码第三版

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值