将具有不同方法签名的不同函数作为 kotlin 中的参数传递给函数
Pass different functions with different method signatures to a function as a parameter in kotlin
我正在开发一个 android 应用程序,使用 kotlin 作为我的主要语言。我需要为应用程序的某些部分请求一些 运行 时间权限。因此,我没有编写类似的样板代码来请求权限,而是决定编写一个单独的静态函数来检查权限,并 运行 一个方法。这是静态函数
fun permissionExecution(childFragment: Fragment, permission: String, expression: ????) {
Dexter.withActivity(childFragment.requireActivity())
.withPermission(permission)
.withListener(object : PermissionListener {
override fun onPermissionGranted(response: PermissionGrantedResponse?) {
expression()
}
override fun onPermissionRationaleShouldBeShown(
permission: PermissionRequest?,
token: PermissionToken
) {
token.continuePermissionRequest()
}
override fun onPermissionDenied(response: PermissionDeniedResponse) {
if(response.isPermanentlyDenied) {
openSettings(childFragment)
}
}
}).check()
}
当我传入不带参数的方法时,这段代码运行良好。但在某些情况下,我想传递具有不同参数类型的方法。
- 像这样调用方法
permissionExecution(childfragment, permission, foo(string))
- 像这样调用相同的方法
permissionExecution(childfrgment, permission, bas(string, Int))
permissionExecution()
方法中的 espression
参数可以使用什么 class 类型
如果我理解正确的话,你已经实现了一个通用的静态函数来检查权限并向它传递一些 lambda,当权限被授予时将调用它。我不明白为什么你这些 lambda 需要一些参数参数。下面的实现是你想要的吗?
class CameraFragment {
fun onCreateView() {
permissionExecution(childFragment = arg1, permission = "perm", expression = {
// open camera
})
}
}
class LocationActivity {
fun onCreate() {
permissionExecution(childFragment = arg1, permission = "perm", expression = {
fetchLocation()
})
}
fun fetchLocation() {
// get location, do stuff
}
}
在 lambda 变量的定义中包含函数参数没有意义。您已经拥有调用这些其他函数所需的一切:
permissionExecution(myFragment, Manifest.permission.RECORD_AUDIO) {
foo(myString)
}
permissionExecution(myFragment, Manifest.permission.CAMERA) {
bar(myString, myInt)
}
如果您需要 PermissionGrantedResponse
来确定这些参数是什么,您可以将其定义为函数输入:
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
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()
}
}
然后每次我需要权限时都这样调用class
1.
Permissions(this, Manifest.permission.READ_CONTACTS, object : Permissions.RunExpression {
override fun expression() {
startActivityForResult(intent, PICK_CONTACT)
}
}).permissionExecution()
2.
Permissions(this, Manifest.permission.READ_CONTACTS, object : Permissions.RunExpression {
override fun expression() {
writeFileToLocation(file, locationPath)
}
}).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)
我正在开发一个 android 应用程序,使用 kotlin 作为我的主要语言。我需要为应用程序的某些部分请求一些 运行 时间权限。因此,我没有编写类似的样板代码来请求权限,而是决定编写一个单独的静态函数来检查权限,并 运行 一个方法。这是静态函数
fun permissionExecution(childFragment: Fragment, permission: String, expression: ????) {
Dexter.withActivity(childFragment.requireActivity())
.withPermission(permission)
.withListener(object : PermissionListener {
override fun onPermissionGranted(response: PermissionGrantedResponse?) {
expression()
}
override fun onPermissionRationaleShouldBeShown(
permission: PermissionRequest?,
token: PermissionToken
) {
token.continuePermissionRequest()
}
override fun onPermissionDenied(response: PermissionDeniedResponse) {
if(response.isPermanentlyDenied) {
openSettings(childFragment)
}
}
}).check()
}
当我传入不带参数的方法时,这段代码运行良好。但在某些情况下,我想传递具有不同参数类型的方法。
- 像这样调用方法
permissionExecution(childfragment, permission, foo(string))
- 像这样调用相同的方法
permissionExecution(childfrgment, permission, bas(string, Int))
permissionExecution()
方法中的 espression
参数可以使用什么 class 类型
如果我理解正确的话,你已经实现了一个通用的静态函数来检查权限并向它传递一些 lambda,当权限被授予时将调用它。我不明白为什么你这些 lambda 需要一些参数参数。下面的实现是你想要的吗?
class CameraFragment {
fun onCreateView() {
permissionExecution(childFragment = arg1, permission = "perm", expression = {
// open camera
})
}
}
class LocationActivity {
fun onCreate() {
permissionExecution(childFragment = arg1, permission = "perm", expression = {
fetchLocation()
})
}
fun fetchLocation() {
// get location, do stuff
}
}
在 lambda 变量的定义中包含函数参数没有意义。您已经拥有调用这些其他函数所需的一切:
permissionExecution(myFragment, Manifest.permission.RECORD_AUDIO) {
foo(myString)
}
permissionExecution(myFragment, Manifest.permission.CAMERA) {
bar(myString, myInt)
}
如果您需要 PermissionGrantedResponse
来确定这些参数是什么,您可以将其定义为函数输入:
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
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()
}
}
然后每次我需要权限时都这样调用class
1.
Permissions(this, Manifest.permission.READ_CONTACTS, object : Permissions.RunExpression {
override fun expression() {
startActivityForResult(intent, PICK_CONTACT)
}
}).permissionExecution()
2.
Permissions(this, Manifest.permission.READ_CONTACTS, object : Permissions.RunExpression {
override fun expression() {
writeFileToLocation(file, locationPath)
}
}).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)