gpt4 book ai didi

java - Firebase Android PhoneAuthProvider 内存泄漏

转载 作者:行者123 更新时间:2023-12-04 15:43:35 30 4
gpt4 key购买 nike

Firebase -> PhoneAuthProvider -> VerifyPhoneNumber 泄漏。我相信,它可能是 OnVerificationStateChangedCallbacks,我们正在调用 verifyPhoneNumber。

重现步骤:

  1. 启动应用
  2. 为基于电话的身份验证选择“PhoneAuthActivity”
  3. 发送电话号码。
  4. 点击返回。

点击返回时出现内存泄露

有人遇到同样的问题吗?任何解决方案?

public void FirebasePhoneUser(String phoneNumber) {
mCallback = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
Log.d("Completed","");
}
@Override
public void onVerificationFailed(FirebaseException e) {
Log.d("Error","");
}

@Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken forceResendingToken) {
Log.d("onCodeSent", "");
}
};
phoneAuthProvider = PhoneAuthProvider.getInstance();
phoneAuthProvider.verifyPhoneNumber(
phoneNumber,
30,
TimeUnit.SECONDS,
TaskExecutors.MAIN_THREAD,
mCallback
);
}

最佳答案

鉴于该 API 很糟糕并且没有取消订阅的选项,您有多种选择来解决这个问题。

  1. 代理或修饰器。您创建另一个 OnVerificationStateChangedCallbacks 将方法调用委托(delegate)给另一个实例:
// this class must be either top-level or 'static'!
public /*static*/ final class DelegatingVerificationStateCallbacks
extends PhoneAuthProvider.OnVerificationStateChangedCallbacks
implements Closeable {
@Nullable private PhoneAuthProvider.OnVerificationStateChangedCallbacks delegate;
public DelegatingVerificationStateCallbacks(
@NonNull PhoneAuthProvider.OnVerificationStateChangedCallbacks delegate
) {
this.delegate = delegate;
}

@Override public void onCodeSent(
@NonNull String verificationId,
@NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken
) {
if (delegate != null) delegate.onCodeSent(verificationId, forceResendingToken);
}
@Override public void onCodeAutoRetrievalTimeOut(@NonNull String s) {
if (delegate != null) delegate.onCodeAutoRetrievalTimeOut(s);
}
@Override public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
if (delegate != null) delegate.onVerificationCompleted(phoneAuthCredential);
}
@Override public void onVerificationFailed(@NonNull FirebaseException e) {
if (delegate != null) delegate.onVerificationFailed(e);
}

@Override public void close() {
delegate = null;
}
}

我已经实现了 Closeable 来进行清理,但您可以实现 RxJava 的 Disposable 或其他替代方法。

此处的使用模式是显而易见且众所周知的:

public final class SomeScreen extends ActivityOrFragmentOrControllerOrWhatever {
private final ArrayList<Closeable> disposeBag = new ArrayList<>();
private void performAuth() {
DelegatingVerificationStateCallbacks callbacks =
new DelegatingVerificationStateCallbacks(
new OnVerificationStateChangedCallbacks() { … }
);
disposeBag.add(callbacks);
phoneAuthProvider.verifyPhoneNumber(…, callbacks);
}
@Override protected void onDestroy() {
for (Closeable c : disposeBag) {
try { c.close(); }
catch (IOException ignored) { }
}
disposeBag.clear();
}
}

结果:Firebase 泄漏了对空且廉价的 DelegatingVerificationStateCallbacks 的引用,而不是对 Activity 的引用。

  1. 将自己的引用置空。您可以采用上面介绍的方法来清除您自己对 Activity 的引用。这意味着这些引用必须是明确的,即。 e.类不能是匿名的或在您的 Activity 中。您必须完全控制类构造函数和字段,顶级类或嵌套的 static 类是一个很好的选择。

  2. 弱引用。这不太明确并且涉及一些间接但仍然有效:您实例化顶级或嵌套的 static 类,将 Activity 传递给构造函数,将其包装在 WeakReference 中,然后分配给一个字段。就是这样,一段时间后 WeakReference#get 将开始返回 null

  3. 反射(reflection)。非常糟糕且不稳定的选项,在某些其他情况下可能会有所帮助。有时您的 Activity 可能会被 Android SDK 或特定于供应商的代码泄露,并且上面的选项不适用。然后你可以自己清空一些私有(private)字段。不要为 Firebase 执行此操作。

关于java - Firebase Android PhoneAuthProvider 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56853611/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com