将具有不同方法签名的不同函数作为kotlin中的参数传递给函数
我正在使用kotlin作为我的主要语言开发一个android应用程序。我需要为应用程序的某些部分请求一些运行时权限。因此,我决定编写一个单独的静态函数来检查权限,并运行一个方法,而不是编写类似的样板代码来请求权限。这里是静态函数将具有不同方法签名的不同函数作为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
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