Java Firebase Android PhoneAuthProvider内存泄漏

Java Firebase Android PhoneAuthProvider内存泄漏,java,android,firebase-authentication,Java,Android,Firebase Authentication,Firebase->PhoneAuthProvider->VerifyPhoneNumber正在泄漏。我相信,这可能是OnVerificationStateChangedCallbacks,我们正在通过电话发送给verifyPhoneNumber 复制步骤: 启动应用程序 选择“PhoneAuthActivity”进行基于电话的身份验证 发送电话号码 单击后退 单击“上一步”时,将显示泄漏的内存 有人也有同样的问题吗?有解决办法吗 public void FirebasePhoneUser(St

Firebase->PhoneAuthProvider->VerifyPhoneNumber正在泄漏。我相信,这可能是OnVerificationStateChangedCallbacks,我们正在通过电话发送给verifyPhoneNumber

复制步骤:

  • 启动应用程序
  • 选择“PhoneAuthActivity”进行基于电话的身份验证
  • 发送电话号码
  • 单击后退
  • 单击“上一步”时,将显示泄漏的内存

    有人也有同样的问题吗?有解决办法吗

    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很糟糕,并且没有取消订阅的选项,您有几个选项可以解决这个问题

  • 代理或装饰。您可以在VerificationStateChangedCallbacks上创建另一个
    ,将方法调用委托给另一个实例:
  • //此类必须是顶级或“静态”类!
    public/*static*/最终类DelegatingVerificationStateCallbacks
    扩展PhoneAuthProvider.OnVerificationStateChangedCallbacks
    可关闭的机具{
    @可为空的私有PhoneAuthProvider.OnVerificationStateChangedCallbacks委托;
    公开授权验证状态回调(
    @非Null PhoneAuthProvider.OnVerificationStateChangedCallbacks委托
    ) {
    this.delegate=委托;
    }
    @覆盖公共区域(
    @非空字符串验证ID,
    @非Null PhoneAuthProvider.ForceResendingToken ForceResendingToken
    ) {
    if(delegate!=null)delegate.onCodeSent(验证ID,forceResendingToken);
    }
    @重写公共void onCodeAutoRetrievalTimeOut(@NonNull字符串s){
    如果(delegate!=null)delegate.oncodeAutorRetrievalTimeout(s);
    }
    @重写公共void onVerificationCompleted(@NonNull PhoneAuthCredential PhoneAuthCredential){
    if(delegate!=null)delegate.onVerificationCompleted(phoneAuthCredential);
    }
    @重写公共void onVerificationFailed(@NonNull FirebaseException e){
    如果(delegate!=null)delegate.onVerificationFailed(e);
    }
    @覆盖公共无效关闭(){
    delegate=null;
    }
    }
    
    我已经为清理实现了
    Closeable
    ,但是您可以实现RxJava的
    一次性的
    或者其他任何东西

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

    public final class SomeScreen扩展了ActivityorFragmentorControllerWhather{
    private final ArrayList disposeBag=new ArrayList();
    私人财产{
    委派验证状态回调回调回调=
    新的DelegatingVerificationStateCallbacks(
    新建OnVerificationStateChangedCallbacks(){…}
    );
    disposeBag.add(回调);
    verifyPhoneNumber(…,回调);
    }
    @重写受保护的void onDestroy(){
    用于(可关闭c:disposeBag){
    试试{c.close();}
    捕获(忽略IOException){}
    }
    disposeBag.clear();
    }
    }
    
    结果:Firebase泄漏对空且廉价的
    委派验证状态回调的引用,而不是对活动的引用

  • 你自己把引用置零。您可以采用上面介绍的方法来清除自己对活动的引用。这意味着这些引用必须是明确的,即。E类不能是匿名的,也不能是活动内部的。您必须完全控制类构造函数和字段,顶级类或嵌套的
    static
    class非常适合

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

  • 反思。非常糟糕且不稳定的选择,在其他情况下可能会有所帮助。有时,您的活动可能会被Android SDK或特定于供应商的代码泄漏,上述选项不适用。然后您可以自己清空一些私有字段。不要为Firebase这样做


  • 你是在金丝雀身上发现的还是什么?我不知道解决方案,我只是想确保您已正确识别问题。是的,使用LeakCana如果您发现Firebase SDK存在明显问题,请向Firebase支持部门提交错误报告,以便他们可以尝试复制并收集信息。堆栈溢出对此无能为力。类似的问题始于2017年,但没有解决方案。这就是我写在这里的原因。不幸的是,这不是很清楚。请记住,仅仅因为在活动运行后内存保持分配状态并不意味着存在泄漏,因为可能会因为验证电话号码的呼叫而导致状态发生变化(以及内存使用情况发生变化)。你认为什么类型的内存被泄露了?你认为它是怎么被泄露的?你认为应该采取什么措施来消除泄漏?