Dígale adiós a onActivityResult, adopte ActivityResultContract

Inserte la descripción de la imagen aquí
Muchos desarrolladores se han onActivityResultquejado durante mucho tiempo: la necesidad de definir resultCodey requestCodeutilizar engorrosos y propensos a errores. Ahora el KTX recién lanzado ActivityResultContractpuede resolver mucho los problemas anteriores

Uso básico


antes de

onActivityResultEscritura tradicional

class MainActivity : AppCompatActivity() {
    
    

    companion object {
    
    
        private const val REQUEST_CODE = 1234
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button_open.setOnClickListener {
    
    
            startActivityForResult(
                    SecondActivity.createIntent(this),
                    REQUEST_CODE
            )
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    
    
        super.onActivityResult(requestCode, resultCode, data)
        Log.d("MainActivity", "requestCode: $requestCode, resultCode: $resultCode, data: $data")
    }
}

SecondActivity debe ser requerido antes de terminarsetResult

setResult(Activity.RESULT_OK, intent)
finish()

Después

Introducir gradle

implementation "androidx.activity:activity-ktx:$latest_vsersion"
  or
implementation "androidx.fragment:fragment-ktx:$latest_vsersion"
class MainActivity : AppCompatActivity() {
    
    

    private val launcher: ActivityResultLauncher<Intent> =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
    
     activityResult ->
                Log.d("MainActivity", activityResult.toString())
            }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button_open.setOnClickListener {
    
    
            launcher.launch(SecondActivity.createIntent(this))
        }
    }
}

Elimina la molesta resultCodesuma requestCode, el código es más elegante
Inserte la descripción de la imagen aquí

Otras escenas


Vea cómo usar ActivityResultContract en varios escenarios comunes:

Seleccionar un documento

Abra el administrador de archivos, seleccione la imagen y regrese uri, primero mire la implementación basada en onActivityResult:

class MainActivity : AppCompatActivity() {
    
    
    companion object {
    
    
        private const val REQUEST_CODE_CHOOSER = 1234
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button_get_content.setOnClickListener {
    
    
            startActivityForResult(
                    Intent(Intent.ACTION_GET_CONTENT).apply {
    
    
                        addCategory(Intent.CATEGORY_OPENABLE)
                        type = "image/*"
                    },
                    REQUEST_CODE_CHOOSER
            )
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    
    
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE_CHOOSER && resultCode == Activity.RESULT_OK) {
    
    
            Log.d("MainActivity", "uri: ${
      
      data?.data}")
        }
    }
}

Después de la implementación basada en ActivityResultContracts:

class MainActivity : AppCompatActivity() {
    
    

    private val launcher = registerForActivityResult(ActivityResultContracts.GetContent()) {
    
     uri ->
        Log.d("MainActivity", "uri: $uri")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button_get_content.setOnClickListener {
    
    
            launcher.launch("image/*")
        }
    }
}

ActivityResultContracts.GetContentEs uno de varios contratos preestablecidos por el sistema: por
Inserte la descripción de la imagen aquí
supuesto, además de los preestablecidos anteriores Contracts, también puede ActivityResultContractspersonalizar sus propios contratos heredando

Solicitud de permiso

El proceso de requestPermission y startActivityForResult es similar:

//权限请求
ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE), REQUEST_CODE)
//返回结果
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    
    
    if (requestCode == REQUEST_CODE) {
    
    
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
    
            Toast.makeText(this, "result: granted", Toast.LENGTH_LONG).show()
        }
        return
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

Implementación basada en ActivityResultContract:

// 设置回调
private val launcher = registerForActivityResult(RequestPermission()) {
    
    
    if (it) {
    
    
        Toast.makeText(this, "result: granted", Toast.LENGTH_LONG).show()
    }
}
// 请求权限
launcher.launch(WRITE_EXTERNAL_STORAGE)

Principio de realización


El principio de ActivityResultContract es relativamente simple, los estudiantes interesados ​​pueden referirse a la comprensión profunda de ActivityResultContracts

Supongo que te gusta

Origin blog.csdn.net/vitaviva/article/details/107551620
Recomendado
Clasificación