解决Android中startActivityForResult()方法已废弃的问题
关于
startActivityForResult被废弃的原因及替代方案 一、废弃原因
startActivityForResult从Android API 30(Android 11)开始被标记为废弃,核心原因是它的回调模式存在诸多弊端:
- 请求码(requestCode)需要手动管理,多个请求时容易出现冲突或混淆
- 回调逻辑集中在
onActivityResult方法中,随着业务复杂会导致代码臃肿、可读性差 - 无法很好地与现代Android组件的生命周期感知特性结合,容易出现内存泄漏或回调丢失的问题
官方推出Activity Result API作为替代方案,它采用更简洁的注册式回调,自动处理生命周期关联,代码结构更清晰。
二、替代方案:使用Activity Result API
以下是针对你的代码的修改步骤,只需要调整MainActivity即可,MoveForResultActivity无需改动:
修改后的MainActivity.java代码
package com.example.praktikump10; import androidx.appcompat.app.AppCompatActivity; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btnMoveActivity; private Button btnMoveWithDataActivity; private Button btnDialPhone; private Button btnMoveWithObject; private Button btnMoveForResult; private TextView tvResult; // 声明ActivityResultLauncher private ActivityResultLauncher<Intent> moveForResultLauncher; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnMoveActivity = findViewById(R.id.btn_move_activity); btnMoveActivity.setOnClickListener(this); btnMoveWithDataActivity = findViewById(R.id.btn_move_activity_data); btnMoveWithDataActivity.setOnClickListener(this); btnDialPhone = findViewById(R.id.btn_dial_number); btnDialPhone.setOnClickListener(this); btnMoveWithObject = findViewById(R.id.btn_move_activity_object); btnMoveWithObject.setOnClickListener(this); btnMoveForResult = findViewById(R.id.btn_move_for_result); btnMoveForResult.setOnClickListener(this); tvResult = findViewById(R.id.tv_result); // 注册ActivityResultLauncher,处理返回结果 moveForResultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == MoveForResultActivity.RESULT_CODE) { Intent data = result.getData(); if (data != null) { int selectedValue = data.getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0); tvResult.setText("Hasil : " + selectedValue); } } } ); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_move_activity: Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); break; case R.id.btn_move_activity_data: Intent moveWithDataIntent = new Intent(MainActivity.this, MoveWithDataActivity.class); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "Hafidz Izdihar Muslim\n"); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 20); startActivity(moveWithDataIntent); break; case R.id.btn_dial_number: String phoneNumber = "087878336770"; Intent dialPhoneIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)); startActivity(dialPhoneIntent); break; case R.id.btn_move_activity_object: Person mPerson = new Person(); mPerson.setName("DicodingAcademy"); mPerson.setAge(5); mPerson.setEmail("academy@dicoding.com"); mPerson.setCity("Bandung"); Intent moveWithObjectIntent = new Intent(MainActivity.this, MoveWithObjectActivity.class); moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, mPerson); startActivity(moveWithObjectIntent); break; case R.id.btn_move_for_result: Intent moveForResultIntent = new Intent(MainActivity.this, MoveForResultActivity.class); // 用launcher启动Activity,替代startActivityForResult moveForResultLauncher.launch(moveForResultIntent); break; } } // 移除原来的onActivityResult方法 }
关键修改点说明
- 移除了原有的
REQUEST_CODE常量和onActivityResult方法 - 添加
ActivityResultLauncher<Intent>变量,并在onCreate中通过registerForActivityResult注册回调逻辑 - 在点击事件中,用
moveForResultLauncher.launch(intent)替代startActivityForResult(intent, REQUEST_CODE) - 回调逻辑直接写在注册时的lambda表达式中,无需再判断requestCode(因为每个launcher对应一个请求场景)
这样修改后,代码结构更清晰,同时避免了原方法的诸多弊端,完全符合Android官方推荐的开发规范。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

