Android监听类无法获取Context,无法创建新Intent如何解决?
问题解决与Context详解
一、解决支付回调中获取Context启动Activity的问题
你的PaymentConnectorListener无法获取Context,是因为没有持有Context引用。可以通过给Listener添加构造函数传入Context,并使用弱引用避免内存泄漏的方式解决,具体修改如下:
修改后的PaymentConnectorListener代码
import android.content.Context; import android.content.Intent; import java.lang.ref.WeakReference; public class PaymentConnectorListener implements IPaymentConnectorListener { private final WeakReference<Context> mContextRef; // 构造函数接收Context,用弱引用持有 public PaymentConnectorListener(Context context) { mContextRef = new WeakReference<>(context); } @Override public void onSaleResponse(SaleResponse response) { Context context = mContextRef.get(); if (context == null) { return; // Context已被回收,终止操作 } String result; Intent targetIntent; if (response.getSuccess()) { result = "Sale was successful"; targetIntent = new Intent(context, PaymentSuccessActivity.class); } else { result = "Sale was unsuccessful: " + response.getReason() + ":" + response.getMessage(); targetIntent = new Intent(context, PaymentFailActivity.class); } targetIntent.putExtra("PAYMENT_RESULT", result); // 非Activity Context启动Activity需要添加NEW_TASK标记 if (!(context instanceof Activity)) { targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } context.startActivity(targetIntent); } }
初始化Listener的代码调整
在Activity中初始化Listener时,直接传入当前Activity的Context(this):
final IPaymentConnectorListener ccListener = new PaymentConnectorListener(this);
为什么用弱引用?
如果直接持有Activity的强引用,当Activity已经销毁但Listener还被PaymentConnector持有,会导致Activity无法被垃圾回收,引发内存泄漏。弱引用会在Activity被回收后自动释放引用,避免这个问题。
二、Android中Context是什么?
类比你熟悉的Angular,Context可以理解为Android应用的环境上下文容器,它提供了访问应用资源、系统服务、启动组件的核心能力,相当于Angular里Injector+组件上下文的结合体,主要作用包括:
- 访问应用资源:获取字符串、图片、布局等资源,比如
context.getString(R.string.app_name),类似Angular中访问assets资源或注入的配置项。 - 启动组件:启动Activity、Service,发送广播,这就是你现在需要的支付回调后启动新页面的能力。
- 获取系统服务:调用系统提供的功能,比如定位、通知、网络请求等,类似Angular中注入的HttpClient、Router等服务。
- 共享全局数据:Application级别的Context可以保存全局变量,生命周期和应用一致,类似Angular中的单例服务。
常见的两种Context类型
- Activity Context:和具体Activity的生命周期绑定,Activity销毁时Context也会被回收。适合启动和当前页面相关的组件,比如打开新Activity时不需要额外标记。
- Application Context:属于整个应用,只要应用在运行就存在。适合获取全局资源、启动后台服务等不需要依赖Activity生命周期的场景,可通过
context.getApplicationContext()获取。
注意事项
- 不要长期持有Activity Context(比如在静态变量、长期存活的回调中),优先用弱引用或Application Context,避免内存泄漏。
- 启动Activity时,如果用的是非Activity Context(比如Application Context),必须添加
Intent.FLAG_ACTIVITY_NEW_TASK标记,否则会抛出异常。
内容的提问来源于stack exchange,提问作者coder123
相关产品推荐
相关产品推荐

