#Android学习#onActivityResult直接回调问题

在学习Android时,遇到startActivityForResult导致的NullPointException异常。问题源于onActivityResult在启动的Activity执行前就被调用。通过研究发现,此问题与被启动Activity在AndroidManifest.xml中的launchMode设置有关。当launchMode设为SingleTask时,onActivityResult会提前执行,改回standard模式则正常。

Android学习,使用startActivityForResult时出现NullPointException异常,通过测试发现,onActivityResult在startActivityForResult启动其他Activity时就立刻被调用,而代码跟教程给出的实例代码是一致的,后来通过这篇文章总结:调用startActivityForResult,onActivityResult无响应的问题才找出问题的原因,原来是处在被启动的Activity的launchMode上。

// Activity A
btnSendParcelable.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, GetDataActivity.class);
                User user = new User("cyfloel", 28, "male");
                intent.putExtra(MainActivity.PARCELABLE_MESSAGE_NAME, user);
                startActivityForResult(intent, 0);
            }
        });
// Activity B
protected void initView() {
        tvDisplay = (TextView) findViewById(R.id.tvDisplay);
        editText = (EditText) findViewById(R.id.editMessage);
        btnSendBack = (Button) findViewById(R.id.btnSendBack);
        btnSendBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent();
                i.putExtra("BACK", editText.getText().toString());
                setResult(1, i);
                finish();
            }
        });
    }
<activity
     android:name=".GetDataActivity"
     android:label="@string/title_activity_get_data"
     android:parentActivityName=".MainActivity"
     android:launchMode="singleTask" // 问题所在
     android:theme="@style/AppTheme.NoActionBar"></activity>

Activity A执行startActivityForResult(intent, 0),没等到被调用的 Activity B执行onClick返回,回调函数onActivityResult() 就被执行了,这与 Activity 的加载模式(launchMode)有关。
原来在AndroidManifest.xml 中Activity B的launchMode设置为SingleTask时,则不需要Activity B返回,onActivityResult就会被执行,而改为standard(默认的模式),则能正常使用。

<activity
     android:name=".GetDataActivity"
     android:label="@string/title_activity_get_data"
     android:parentActivityName=".MainActivity"
     android:launchMode="standard" //设为标准模式即可正常使用
     android:theme="@style/AppTheme.NoActionBar"></activity>
Note that this method should only be used with Intent protocols
     * that are defined to return a result.  In other protocols (such as
     * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
     * not get the result when you expect.  For example, if the activity you
     * are launching uses the singleTask launch mode, it will not run in your
     * task and thus you will immediately receive a cancel result.
是的,**`onActivityResult` 是一种回调机制**。 --- ### 🔍 什么是 `onActivityResult`? `onActivityResult` 是 Android 中用于**接收其他 Activity 返回结果**的回调方法。当你在一个 Activity 中调用 `startActivityForResult()` 启动另一个 Activity 时,被启动的 Activity 可以通过 `setResult()` 返回数据,系统会回调原始 Activity 的 `onActivityResult()` 方法。 --- ### ✅ 示例代码: #### 启动另一个 Activity 并请求结果: ```kotlin val intent = Intent(this, SecondActivity::class.java) startActivityForResult(intent, REQUEST_CODE) ``` #### 接收返回结果: ```kotlin override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) { val result = data?.getStringExtra("result_key") Toast.makeText(this, "收到结果:$result", Toast.LENGTH_SHORT).show() } } ``` --- ### 🧠 它为什么是回调? - 回调的本质是:**在某个事件发生后,系统自动调用你的方法**。 - `onActivityResult()` 就是这样一个机制:当目标 Activity 返回结果时,系统会“回调”这个方法,通知你结果已经返回。 --- ### ⚠️ 注意:`onActivityResult` 已被废弃(在 Activity 和 Fragment 中) 从 **AndroidX Activity 和 Fragment 1.2.0 开始**,官方推荐使用 **`ActivityResultLauncher` + `ActivityResultContracts`** 的新 API 来替代 `onActivityResult()`,它基于回调机制,但更安全、结构更清晰。 --- ### ✅ 新方式:使用 `ActivityResultLauncher`(推荐) #### 1. 在 Activity 或 Fragment 中声明 launcher: ```kotlin private lateinit var launcher: ActivityResultLauncher<Intent> ``` #### 2. 初始化: ```kotlin launcher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> if (result.resultCode == RESULT_OK) { val data = result.data?.getStringExtra("result_key") Toast.makeText(this, "收到结果:$data", Toast.LENGTH_SHORT).show() } } ``` #### 3. 使用: ```kotlin val intent = Intent(this, SecondActivity::class.java) launcher.launch(intent) ``` --- ### ✅ 总结: | 问题 | 回答 | |------|------| | `onActivityResult` 是回调吗? | ✅ 是的,它是典型的回调方法 | | 原理是什么? | 系统在目标 Activity 返回结果后,自动调用该方法 | | 是否已过时? | 是,在现代开发中推荐使用 `ActivityResultLauncher` | | 为什么推荐新方式? | 更灵活、类型安全、生命周期绑定更好 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值