Activity Result API詳解


  以下學習自https://blog.csdn.net/guolin_blog/article/details/121063078?spm=1001.2014.3001.5501

  startActivityForResult()方法如今已經被廢棄了,官方推薦的是使用Activity Result API來實現兩個Activity之間傳遞數據功能。但Activity Result API時能做的事還有很多,下面來學習一下怎么使用。

兩個Activity之間交換數據

  傳統的寫法就是使用startActivityForResult()方法傳入intent和請求碼,然后會回調到onActivityResult()中,在這里面進行返回數據的處理。使用Activity Result API的話,SecondActivity的代碼是不用修改的,如下:

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        val btn = findViewById<Button>(R.id.btn)
        btn.setOnClickListener {
            val intent = Intent()
            intent.putExtra("data", "this is secondactivity")
            setResult(RESULT_OK, intent)
            finish()
        }
    }
}

 

 

  只需要修改第一個Activity中的代碼:

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

        binding.toNext.setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java)
            requestDataLauncher.launch(intent)
        }
    }
    private val requestDataLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == RESULT_OK) {
            val data = result.data?.getStringExtra("data")
            Log.i(TAG, data.toString())
        }
    }

  現在只需要調用registerForActivityResult()方法來注冊一個對Activity結果的監聽。

  此方法接收兩個參數,第一個是Contract類型,第二個是一個Lambda表達式,當有結果返回時會回調到這里,在這里獲取並處理數據就行。

 

請求運行時權限

  requestPermissions()方法也被廢棄了。同樣推薦使用Activity Result API,不過這挺好,使用起來非常簡單。如下:

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

        binding.toNext.setOnClickListener {
            requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
        }
    }
    private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
        if (granted) {
            Log.i(TAG, "允許: ")
        } else {
            Log.i(TAG, "不允許: ")
        }
    }

  使用同樣的方法,只不過需要將Contract類型改成RequestPermission,同時修改傳入的參數。至於每種Contract需要傳入什么類型的參數,可以前往它的源碼查看,比如上面這個:

    public static final class RequestPermission extends ActivityResultContract<String, Boolean> {

  第一個String就是請求的權限名,第二個就是布爾類型的參數作為返回結果。

  對了,別忘了去AndroidManifest中添加用戶權限:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

 

內置Contract

  以下是內置的一些Contract,通過名字就能判斷出是干什么的了:

StartActivityForResult()
StartIntentSenderForResult()
RequestMultiplePermissions()
RequestPermission()
TakePicturePreview()
TakePicture()
TakeVideo()
PickContact()
GetContent()
GetMultipleContents()
OpenDocument()
OpenMultipleDocuments()
OpenDocumentTree()
CreateDocument()

 

 

區分數據來源

  當一個Activity需要接收其他多個Activity的結果時,由於沒有requestCode,所以就要采用為每個結果注冊一個監聽器,如下:

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

        binding.toSecond.setOnClickListener {
            val intent = Intent(Intent.ACTION_VIEW)
            actionViewLauncher.launch(intent)
        }
        binding.toThree.setOnClickListener {
            val intent = Intent(Intent.ACTION_DIAL)
            actionDailLauncher.launch(intent)
        }

    }

    private val actionViewLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->

    }
    private val actionDailLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM