首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确使用registerForActivityResult?获取"LifecycleOwners必须在启动前调用注册表“

如何正确使用registerForActivityResult?获取"LifecycleOwners必须在启动前调用注册表“
EN

Stack Overflow用户
提问于 2021-07-16 16:12:41
回答 2查看 975关注 0票数 1

我使用registerForActivityResult就像这样:

代码语言:javascript
复制
package com.example.livedata

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.ActivityNotFoundException
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.example.livedata.databinding.ActivityAddBinding
import com.example.livedata.databinding.DialogCustomImageSelectionBinding


class AddActivity : AppCompatActivity(), View.OnClickListener {
    private lateinit var binding: ActivityAddBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityAddBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setupActionBar()

        binding.photoAdd.setOnClickListener(this)
    }

    private fun setupActionBar() {
        setSupportActionBar(binding.toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        binding.toolbar.setNavigationOnClickListener { onBackPressed() }
    }

    override fun onClick(v: View?) {
        if (v != null) {
            when (v.id) {
                R.id.photo_add -> {
                    imageDialog()
                    return
                }
            }
        }
    }

    private fun imageDialog() {
        val dialog = Dialog(this)
        val dialogBinding: DialogCustomImageSelectionBinding =
            DialogCustomImageSelectionBinding.inflate(layoutInflater)
        dialog.setContentView(dialogBinding.root)
        dialog.show()

        dialogBinding.impCamera.setOnClickListener {
            registerForActivityResult(ActivityResultContracts.TakePicturePreview()) {
                if (it != null) {
                    Toast.makeText(this@AddActivity, "TakePicturePreview", Toast.LENGTH_SHORT).show()
                }
            }.launch(null).apply { arrayOf(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA) }
            dialog.dismiss()
        }

    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
            data?.let {
                val bp = data.getParcelableExtra<Bitmap>("data")
                binding.imageView.setImageBitmap(bp)

            }
        }
    }

    private fun showPermissions() {
        AlertDialog.Builder(this).setMessage("Applay Permissions!")
            .setPositiveButton("Go to Settings") { _, _ ->
                try {
                    val intel = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    val uri = Uri.fromParts("package", packageName, null)
                    intel.data = uri
                    startActivity(intel)
                } catch (e: ActivityNotFoundException) {
                    e.printStackTrace()
                }
            }.setNegativeButton("Cancel") { dialog, _ ->
                dialog.dismiss()
            }.show()
    }
}

但是它不能工作并在这里抛出一个异常:

代码语言:javascript
复制
2021-07-16 15:38:50.472 29885-29885/com.example.livedata E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.livedata, PID: 29885
    java.lang.IllegalStateException: LifecycleOwner com.example.livedata.AddActivity@9fc53b9 is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
        at androidx.activity.result.ActivityResultRegistry.register(ActivityResultRegistry.java:123)
        at androidx.activity.ComponentActivity.registerForActivityResult(ComponentActivity.java:659)
        at androidx.activity.ComponentActivity.registerForActivityResult(ComponentActivity.java:668)
        at com.example.livedata.AddActivity.imageDialog$lambda-3(AddActivity.kt:68)
        at com.example.livedata.AddActivity.lambda$N7K_EbTML-ycmUwpA7-i8b_L-Sw(Unknown Source:0)
        at com.example.livedata.-$$Lambda$AddActivity$N7K_EbTML-ycmUwpA7-i8b_L-Sw.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:7281)
        at android.view.View.performClickInternal(View.java:7255)
        at android.view.View.access$3600(View.java:828)
        at android.view.View$PerformClick.run(View.java:27925)
        at android.os.Handler.handleCallback(Handler.java:900)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:219)
        at android.app.ActivityThread.main(ActivityThread.java:8393)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
2021-07-16 15:38:50.539 1689-2062/? E/InputDispatcher: channel 'ba7a009 com.example.livedata/com.example.livedata.AddActivity (server)' ~ Channel is unrecoverably broken and will be disposed!

如何使用registerForActivityResult而不是过时的方法来完成此任务?所有的帮助都非常感谢。

EN

回答 2

Stack Overflow用户

发布于 2021-07-16 19:47:31

下面的代码代替了startActivityForResult的弃用,这个方法给出结果本身并返回一个值。

代码语言:javascript
复制
val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    when (result.resultCode) {
        Activity.RESULT_OK -> {
            // logic
        }
        else -> {
            // logic
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2021-07-17 11:56:33

您正在尝试调用单击侦听器中的registerForActivityResult。这是行不通的,因为在结果交付之前,您的Activity可能会被销毁并重新创建。重新创建的Activity不会被注册来接收结果,因为它只在您单击按钮时注册,并且该按钮只在原始Activity中单击。

要解决此问题,您需要无条件地调用registerForActivityResult并将结果存储在一个变量中:

代码语言:javascript
复制
class MyActivity : AppCompatActivity() {
    private val activityLauncher = registerForActivityResult(...

这样,重新创建的Activity将被注册以接收结果。然后使用该activityLauncher变量从单击listener按钮启动它。

有关详细信息,请参阅official guide

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68405703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档