Передавать различные функции с разными сигнатурами методов в функцию в качестве параметра в kotlin - PullRequest
0 голосов
/ 26 мая 2020

Я работаю над приложением android, используя kotlin в качестве основного языка. Мне нужно было спросить разрешения на выполнение для некоторых частей приложения. Поэтому вместо того, чтобы писать аналогичный шаблонный код для запроса разрешений, я решил написать отдельную функцию stati c, которая проверяет наличие разрешения и запускает метод. Вот stati c function

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()
}

Этот код отлично работает, когда я передал методы без аргументов. Но у меня есть ситуации, когда я хотел бы передать методы с разными типами аргументов.

  1. вызов метода, подобного этому permissionExecution(childfragment, permission, foo(string))
  2. вызов того же метода, как этот permissionExecution(childfrgment, permission, bas(string, Int))

какой тип класса я могу использовать для espression аргумент в методе permissionExecution()

Ответы [ 4 ]

1 голос
/ 26 мая 2020

Не имеет смысла включать параметры функции в определение лямбда-элемента. У вас уже есть все необходимое для вызова этих других функций:

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)
}
0 голосов
/ 27 мая 2020

лучший способ найти, адаптировав решение здесь - это во-первых, создать такой интерфейс

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)
0 голосов
/ 27 мая 2020

здесь не очень изящное решение. Я создаю класс-оболочку с одним интерфейсом метода, подобным этому

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()
}

}

, а затем вызываю такой класс каждый раз, когда мне нужно разрешение

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()
0 голосов
/ 26 мая 2020

Если я правильно понимаю, вы реализовали общую статистику c fun c, которая проверяет разрешение и передает ему некоторую лямбду, которая будет вызываться при предоставлении разрешения. Я не понимаю, зачем вам эти лямбды нужны какие-то параметры аргумента. Желаете ли вы приведенную ниже реализацию?

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
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...