如何从AuthWebViewActivity向调用类Auth返回数据?
从AuthWebViewActivity向Auth返回数据的方案
一、实现方式:借助宿主Activity的结果回调
因为Auth本身不是Activity,它持有的Context其实是LoginActivity的实例,所以需要通过LoginActivity的生命周期接收AuthWebViewActivity的返回结果,再把结果传递给Auth处理——这样既能保持AuthWebViewActivity的简洁,又能把所有认证逻辑集中在Auth里。
1. 推荐:使用AndroidX的ActivityResultContracts
这是Google推荐替代旧版startActivityForResult的方案,更安全且具备生命周期感知能力:
步骤1:在LoginActivity中注册结果回调并传给Auth
// LoginActivity.kt class LoginActivity : AppCompatActivity() { private lateinit var auth: Auth override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) // 注册Activity结果回调 val authResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { // 将返回的数据交给Auth处理 auth.handleAuthResult(result.data) } } // 创建Auth实例时传入回调Launcher auth = Auth(this, authResultLauncher) } }
步骤2:修改Auth类,用Launcher启动Activity并处理结果
// Auth.kt class Auth( private val context: Context, private val resultLauncher: ActivityResultLauncher<Intent> ) { // 对外暴露的启动认证页面方法 fun startAuthFlow(url: String) { val intent = Intent(context, AuthWebViewActivity::class.java) intent.putExtra("url", url) resultLauncher.launch(intent) } // 处理AuthWebViewActivity返回的认证数据 fun handleAuthResult(data: Intent?) { val authToken = data?.getStringExtra("auth_token") // 这里写所有后续认证逻辑:存token、校验、请求接口等 } }
步骤3:在AuthWebViewActivity中返回数据
// AuthWebViewActivity.kt class AuthWebViewActivity : AppCompatActivity() { // 假设WebView加载完成后获取到了认证token private fun onAuthCompleted(token: String) { val resultIntent = Intent().apply { putExtra("auth_token", token) } setResult(RESULT_OK, resultIntent) finish() } }
2. 兼容旧版:使用startActivityForResult
如果项目还在使用旧版API,可采用这种方式:
步骤1:LoginActivity重写onActivityResult并传给Auth
// LoginActivity.kt class LoginActivity : AppCompatActivity() { private lateinit var auth: Auth override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) auth = Auth(this) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == Auth.AUTH_REQUEST_CODE && resultCode == RESULT_OK) { auth.handleAuthResult(data) } } }
步骤2:Auth类调用startActivityForResult
// Auth.kt class Auth(private val activity: Activity) { companion object { const val AUTH_REQUEST_CODE = 1001 } fun startAuthFlow(url: String) { val intent = Intent(activity, AuthWebViewActivity::class.java) intent.putExtra("url", url) activity.startActivityForResult(intent, AUTH_REQUEST_CODE) } fun handleAuthResult(data: Intent?) { // 处理认证结果逻辑 } }
二、关于Auth类启动Activity的设计建议
- 避免内存泄漏:直接持有Activity的强引用容易导致内存泄漏,建议改用
WeakReference包裹Activity:
class Auth(private val activityRef: WeakReference<Activity>) { fun startAuthFlow(url: String) { val activity = activityRef.get() ?: return // 若Activity已销毁则不执行 val intent = Intent(activity, AuthWebViewActivity::class.java) intent.putExtra("url", url) activity.startActivityForResult(intent, AUTH_REQUEST_CODE) } } // LoginActivity中创建实例:auth = Auth(WeakReference(this))
- 设计合理性:让AuthWebViewActivity只负责WebView展示和结果收集,所有认证逻辑放在Auth中是符合单一职责原则的,这个设计方向没问题。如果Auth需要全局复用,可以考虑设计成单例,但要注意传入的Context必须是Activity类型(启动Activity必须用Activity Context)。
内容的提问来源于stack exchange,提问作者danshat
相关产品推荐
相关产品推荐

