将具有不同方法签名的不同函数作为kotlin中的参数传递给函数

将具有不同方法签名的不同函数作为kotlin中的参数传递给函数,kotlin,android-permissions,higher-order-functions,Kotlin,Android Permissions,Higher Order Functions,我正在使用kotlin作为我的主要语言开发一个android应用程序。我需要为应用程序的某些部分请求一些运行时权限。因此,我决定编写一个单独的静态函数来检查权限,并运行一个方法,而不是编写类似的样板代码来请求权限。这里是静态函数 fun permissionExecution(childFragment:Fragment,permission:String,expression:??){ Dexter.withActivity(childFragment.requireAction()) .wi

我正在使用kotlin作为我的主要语言开发一个android应用程序。我需要为应用程序的某些部分请求一些运行时权限。因此,我决定编写一个单独的静态函数来检查权限,并运行一个方法,而不是编写类似的样板代码来请求权限。这里是静态函数

fun permissionExecution(childFragment:Fragment,permission:String,expression:??){
Dexter.withActivity(childFragment.requireAction())
.withPermission(许可)
.withListener(对象:PermissionListener{
覆盖已授予的权限(响应:PermissionGrantedResponse?){
表达式()
}
覆盖权限上的乐趣合理应显示(
许可:许可请求?,
令牌:PermissionToken
) {
token.continuePermissionRequest()的
}
override fun onPermissionDenied(响应:PermissionDeniedResponse){
如果(响应。被永久拒绝){
openSettings(childFragment)
}
}
}).检查()
}
当我传入没有参数的方法时,这段代码可以完美地工作。但在某些情况下,我希望传入具有不同参数类型的方法

  • 像这样调用方法
    permissionExecution(childfragment,permission,foo(string))
  • 像这样调用相同的方法
    permissionExecution(childfrugment,permission,bas(string,Int))

  • permissionExecution()
    方法中的
    espression
    参数可以使用什么类类型如果我理解正确,您已经实现了一个通用的静态func,该函数检查权限并向其传递一些lambda,在授予权限时将调用它。我不明白为什么这些lambda需要一些参数。下面的实现是您想要的吗

    类CameraFragment{
    乐趣onCreateView(){
    permissionExecution(childFragment=arg1,permission=“perm”,表达式={
    //开放式摄像机
    })
    }
    }
    班级定位活动{
    fun onCreate(){
    permissionExecution(childFragment=arg1,permission=“perm”,表达式={
    fetchLocation()
    })
    }
    有趣的地点(){
    //获取位置,做些事情
    }
    }
    
    在lambda参数的定义中包含函数参数是没有意义的。您已经拥有调用这些其他函数所需的一切:

    permissionExecution(myFragment, Manifest.permission.RECORD_AUDIO) {
        foo(myString)
    }
    
    permissionExecution(myFragment, Manifest.permission.CAMERA) {
        bar(myString, myInt)
    }
    
    如果需要
    permissiongrantedsponse
    来确定这些参数是什么,可以将其定义为函数输入:

    fun permissionExecution(childFragment: Fragment, permission: String, expression: (PermissionGrantedResponse) -> Unit) {
    
        Dexter.withActivity(childFragment.requireActivity())
            .withPermission(permission)
            .withListener(object : PermissionListener {
                override fun onPermissionGranted(response: PermissionGrantedResponse) {
                    expression(response)
                }
        //...
    }
    
    //...
    
    permissionExecution(myFragment, Manifest.permission.RECORD_AUDIO) { response ->
        foo(response.permissionName)
    }
    

    这里有一个不那么优雅的解决方案。我创建了一个具有如下单个方法接口的包装器类

    class Permissions(val childFragment: Fragment, private val permission: String, val runExpression: RunExpression) {
    interface RunExpression{
        fun expression()
    }
    
    fun permissionExecution() {
    
        Dexter.withActivity(childFragment.requireActivity())
            .withPermission(permission)
            .withListener(object : PermissionListener {
                override fun onPermissionGranted(response: PermissionGrantedResponse?) {
                    runExpression.expression()
                }
    
                override fun onPermissionRationaleShouldBeShown(
                    permission: PermissionRequest?,
                    token: PermissionToken
                ) {
                    token.continuePermissionRequest()
                }
    
                override fun onPermissionDenied(response: PermissionDeniedResponse) {
                    if(response.isPermanentlyDenied) {
                        openSettings(childFragment)
                    }
                }
    
            }).check()
    }
    
    }

    然后每次我需要许可的时候都这样叫这个班

    一,

    权限(此,Manifest.permission.READ\u联系人,对象:Permissions.RunExpression{
    覆盖有趣的表达式(){
    startActivityForResult(意向、选择联系人)
    }
    }).permissionExecution()
    
    二,

    权限(此,Manifest.permission.READ\u联系人,对象:Permissions.RunExpression{
    覆盖有趣的表达式(){
    writeFileToLocation(文件,位置路径)
    }
    }).permissionExecution()
    
    通过调整解决方案,我找到了一个更好的方法,首先,创建一个这样的界面

    interface RunExpression{
    fun expression()}
    
    然后在函数签名中使用接口

    fun permissionExecution(childFragment: Fragment, permission : String, runExpression: RunExpression) {
    
    Dexter.withActivity(childFragment.requireActivity())
        .withPermission(permission)
        .withListener(object : PermissionListener {
            override fun onPermissionGranted(response: PermissionGrantedResponse?) {
                runExpression.expression()
            }
    
            override fun onPermissionRationaleShouldBeShown(
                permission: PermissionRequest?,
                token: PermissionToken
            ) {
                token.continuePermissionRequest()
            }
    
            override fun onPermissionDenied(response: PermissionDeniedResponse) {
                if(response.isPermanentlyDenied) {
                    openSettings(childFragment)
                }
            }
    
        }).check()}
    
    然后,无论我想在哪里调用函数,我都会将实现接口的匿名对象保存到一个变量中

    val startMyActivity = object : RunExpression {
                override fun expression() {
                    startActivityForResult(intent, PICK_CONTACT)
                }
            }
    
    然后用变量调用函数

    permissionExecution(this, Manifest.permission.READ_CONTACTS, startMyActivity)
    

    所以,当
    onpermissiongrated
    时,您希望从不同的屏幕执行一些lambda,对吗?
    onpermissiongrated
    中是否只有
    expression()
    ?我想说重载这个函数,因为如果你动态地使用这个函数,你仍然需要在调用它之前通过检查来了解里面的东西。@sonnet,是的。让我这样解释,写入外部存储器、读取电话联系人、使用手机摄像头等过程都需要不同的android访问权限,这需要类似的请求权限的方法。首先,检查权限,如果授予,则运行一段代码(即表达式方法)。大多数情况下,由于方法签名的原因,每个表达式方法都是不同的。我正在为表达式寻找一个包罗万象的方法签名。@AnimeshSahu,编写重载将要求我为每个方法签名编写单独的签名,这是我首先要避免的。am调用的函数在
    permissionExecution
    函数中没有影响,只是需要被调用。我不明白您为什么需要更改
    表达式的签名<代码>()->单元
    很好,因为您的func
    权限执行
    很常见。只要把你想要的其他课程的lambda递给我,谢谢你的兴趣。但让我再次重申问题的要点,
    permissionexecution
    方法是一种静态方法。我感兴趣的是一种表达式类型,它可以处理任何输入参数类型的函数,只要它的返回类型是unit,就没有这种东西。具有不同参数数的函数的共同祖先是
    Any
    permissionExecution
    函数如何知道这些参数要传递什么?谢谢大家的关注。但让我再次重申问题的要点,
    permissionexecution
    方法是一种静态方法。我感兴趣的是一种表达式类型,它可以处理任何输入参数类型的函数,只要它的返回类型是unit。表达式可以是
    startActivityForResult(intent