【问题标题】:BiometricPrompt: BiometricFragment and Activity memory leakBiometricPrompt:BiometricFragment 和 Activity 内存泄漏
【发布时间】:2020-05-07 01:22:24
【问题描述】:

您好,我发现 2 个内存泄漏需要解决。

收到回调onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result)后,想setResult()在ActivityB上调用finish()回到ActivityA。
尽管这确实可以正常工作,但在调用 finish() 后似乎会导致 2 次内存泄漏。

2 LeakCanary screenshots

这里是重现内存泄漏(ActivityB)的相关代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);;
    BiometricPrompt biometricPrompt = biometricPromptInstance();
    biometricPrompt.authenticate(buildPromptInfo());
}

private BiometricPrompt biometricPromptInstance(){
    Executor executor = ContextCompat.getMainExecutor(this);;
    BiometricPrompt.AuthenticationCallback callback = new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {

        }

        @Override
        public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
            setResult(RESULT_OK);

            //Causing leak:  ////////////////////////////////////////////////
            finish();
            /////////////////////////////////////////////////////////////////
        }

        @Override
        public void onAuthenticationFailed() {

        }
    };
    return new BiometricPrompt(this, executor, callback);
}

private BiometricPrompt.PromptInfo buildPromptInfo(){
    return new BiometricPrompt.PromptInfo.Builder()
            .setTitle("Login")
            .setSubtitle("Log in using your biometric credential")
            .setNegativeButtonText("Cancel")
            .build();
}

【问题讨论】:

  • 你应该只是report a bug against Biometric
  • @ianhanniballake 感谢您的提示,我会这样做,如果我得到他们的回复,我会在这里分享。
  • @MoisesMartinez 有什么更新吗?
  • @Besnik 看来谷歌仍在努力:issuetracker.google.com/issues/144919472
  • 我发现使用应用程序上下文创建执行器似乎可以解决这些问题。使用“executor = ContextCompat.getMainExecutor(getApplicationContext());”

标签: android memory-leaks androidx android-fingerprint-api android-biometric-prompt


【解决方案1】:

问题在于执行器的初始化,

// initialize biometric executor
executor = ContextCompat.getMainExecutor(this)

更新到

// initialize biometric executor
executor = ContextCompat.getMainExecutor(applicationContext)

在内部,Google 使用 Handler 在新线程中执行操作。上下文关联不应该是您的 Activity(或 Fragment)。

/**
 * Return an {@link Executor} that will run enqueued tasks on the main
 * thread associated with this context. This is the thread used to dispatch
 * calls to application components (activities, services, etc).
 */
public static Executor getMainExecutor(Context context) {
    if (Build.VERSION.SDK_INT >= 28) {
        return context.getMainExecutor();
    }
    return new MainHandlerExecutor(new Handler(context.getMainLooper()));
}

private static class MainHandlerExecutor implements Executor {
    private final Handler mHandler;

    MainHandlerExecutor(@NonNull Handler handler) {
        mHandler = handler;
    }

    @Override
    public void execute(Runnable command) {
        if (!mHandler.post(command)) {
            throw new RejectedExecutionException(mHandler + " is shutting down");
        }
    }
}

【讨论】:

    猜你喜欢
    • 2018-03-29
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 2013-11-08
    • 2016-05-03
    相关资源
    最近更新 更多