Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 无法找到内存泄漏_Android_Memory Leaks_Leakcanary - Fatal编程技术网

Android 无法找到内存泄漏

Android 无法找到内存泄漏,android,memory-leaks,leakcanary,Android,Memory Leaks,Leakcanary,我可以看到leakcanary在下面的代码中抱怨FingerprintManager.mContext中内存泄漏。我在AsyncTask中尝试了静态内部类和WeakReference。无法找到导致内存泄漏的代码 class BiometricHelper(var localListener: BiometricHelperListener, val fragmentActivity: FragmentActivity) : BiometricPrompt.AuthenticationCallba

我可以看到leakcanary在下面的代码中抱怨FingerprintManager.mContext中内存泄漏。我在AsyncTask中尝试了静态内部类和WeakReference。无法找到导致内存泄漏的代码

class BiometricHelper(var localListener: BiometricHelperListener, val fragmentActivity: FragmentActivity) : BiometricPrompt.AuthenticationCallback() {

    private val mListener: WeakReference<BiometricHelper.BiometricHelperListener> = WeakReference(localListener)

    private val mFragmentActivity: WeakReference<FragmentActivity> = WeakReference(fragmentActivity)

    val mEditor: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(TransfastApplication.getContext())


    private val TAG = BiometricHelper::class.java!!.getName()

    private var mkeyStore: KeyStore? = null
    private var mgenerator: KeyGenerator? = null
    private var mcipher: Cipher? = null
    private val KEYSTORE = "somevalue"
    private val PREFERENCES_KEY_IV = "somevalue"
    private val PREFERENCES_KEY_PASS = "somevalue"
    private var mcryptoObject: BiometricPrompt.CryptoObject? = null

    private var encrypting: Boolean = false
    private var mEmail: String? = null
    private var mPassword: String? = null


    private var mAuthTask: BiometricHelper.UserLoginTask? = null

    private lateinit var myBiometricPrompt: BiometricPrompt


    interface BiometricHelperListener {
        fun onAuthenticationSuccessful(result: BiometricPrompt.AuthenticationResult)
        fun onSavedUserAuthenticationSuccessful(password: String)
        fun onAuthenticationFailed(error: String)
        fun onFingerPrintRegistrationDenied()
        fun onNoBiometricSupport()
    }

    public fun registerAuthentication(email: String, password: String) {
        this.mEmail = email;
        this.mPassword = password;
        mAuthTask = UserLoginTask(this, mEditor, email, password)
        mAuthTask?.execute(null as Void?)
    }

    public fun authenticateExistingUser(email: String) {
        this.mEmail = email
        mAuthTask = UserLoginTask(this, mEditor);
        mAuthTask?.execute(null as Void?)
    }

    private fun startAuth(isRegister: Boolean) {

        val executor = Executors.newSingleThreadExecutor()
        myBiometricPrompt = BiometricPrompt(mFragmentActivity.get()!!, executor, this)
        if (mcryptoObject != null) {

            if (isRegister) {
                val promptInfo = BiometricPrompt.PromptInfo.Builder()

                        .setTitle("Enable Fingerprint")
                        .setSubtitle(mFragmentActivity.get()!!.resources.getString(R.string.fingerprint_confirm_message))
                        //.setDescription(mFragmentActivity.get()!!.resources.getString(R.string.fingerprint_confirm_description))
                        .setNegativeButtonText(mFragmentActivity.get()!!.resources.getString(R.string.text_cancel))
                        .build()
                myBiometricPrompt.authenticate(promptInfo, mcryptoObject!!)
            } else {
                val promptInfo = BiometricPrompt.PromptInfo.Builder()
                        .setTitle("Login")
                        .setSubtitle(mEmail)
                        .setNegativeButtonText(mFragmentActivity.get()!!.resources.getString(R.string.text_cancel))
                        .build()
                myBiometricPrompt.authenticate(promptInfo, mcryptoObject!!)
            }


        }

    }

    public fun isUserRegistered(): Boolean {

        if (mEditor.getString(PREFERENCES_KEY_PASS, null) != null) {
            return true;
        }

        return false;
    }


    public fun checkBiometricSupport(): Boolean {


        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) //currently support library does not support Android M
            return false;

        val keyguardManager = mFragmentActivity.get()?.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager

        if (!keyguardManager.isKeyguardSecure) {
            false
        }

        val fingerprintManagerCompat = FingerprintManagerCompat.from(mFragmentActivity.get()!!)

        if (!fingerprintManagerCompat.hasEnrolledFingerprints()) {
            return false;
        }

        if (ActivityCompat.checkSelfPermission(mFragmentActivity.get()!!,
                        Manifest.permission.USE_BIOMETRIC) != PackageManager.PERMISSION_GRANTED) {
            false
        }

        return if (mFragmentActivity.get()!!.packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
            true
        } else true
    }


    private fun getKeyStore(): Boolean {
        try {
            mkeyStore = KeyStore.getInstance(KEYSTORE)
            mkeyStore?.load(null) // Create empty keystore
            return true
        } catch (e: KeyStoreException) {
        } catch (e: CertificateException) {
        } catch (e: NoSuchAlgorithmException) {
        } catch (e: IOException) {
        }

        return false
    }


    @TargetApi(Build.VERSION_CODES.M)
    fun createNewKey(forceCreate: Boolean): Boolean {
        try {
            if (forceCreate)
                mkeyStore?.deleteEntry(PrefManager.getInstance().keyAlias)
            if (!mkeyStore?.containsAlias(PrefManager.getInstance().keyAlias)!!) {
                mgenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, KEYSTORE)

                mgenerator?.init(KeyGenParameterSpec.Builder(PrefManager.getInstance().keyAlias,
                        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
                        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                        .setUserAuthenticationRequired(true)
                        .build()
                )

                mgenerator?.generateKey()
            }
            return true
        } catch (e: Exception) {

        }
        return false
    }

    private fun getCipher(): Boolean {
        try {
            mcipher = Cipher.getInstance(
                    KeyProperties.KEY_ALGORITHM_AES + "/"
                            + KeyProperties.BLOCK_MODE_CBC + "/"
                            + KeyProperties.ENCRYPTION_PADDING_PKCS7)

            return true
        } catch (e: NoSuchAlgorithmException) {

        } catch (e: NoSuchPaddingException) {

        }

        return false
    }


    public fun isNewFingerprintEnrolled(): Boolean {
        getKeyStore()
        getCipher()
        return !initCipher(Cipher.DECRYPT_MODE);
    }

    @TargetApi(Build.VERSION_CODES.M)
    public fun initCipher(mode: Int): Boolean {
        try {
            mkeyStore?.load(null)
            val keyspec = mkeyStore?.getKey(PrefManager.getInstance().keyAlias, null) as SecretKey

            if (mode == Cipher.ENCRYPT_MODE) {
                mcipher?.init(mode, keyspec)
                var localEditor = mEditor.edit()
                localEditor.putString(PREFERENCES_KEY_IV, Base64.encodeToString(mcipher?.getIV(), Base64.NO_WRAP)).commit()
            } else {
                val iv = Base64.decode(mEditor.getString(PREFERENCES_KEY_IV, ""), Base64.NO_WRAP)
                val ivspec = IvParameterSpec(iv)
                mcipher?.init(mode, keyspec, ivspec)
            }

            return true
        } catch (e: Exception) {
            clearSavedData()
        }

        return false
    }

    @TargetApi(Build.VERSION_CODES.M)
    private fun initCryptObject(): Boolean {
        try {
            mcryptoObject = mcipher?.let { BiometricPrompt.CryptoObject(it) }
            return true
        } catch (ex: Exception) {
        }

        return false
    }

    fun encryptString(password: String) {
        try {
            val bytes = mcipher?.doFinal(password.toByteArray())
            val encryptedText = Base64.encodeToString(bytes, Base64.NO_WRAP)
            var localEditor = mEditor.edit()
            localEditor.putString(PREFERENCES_KEY_PASS, encryptedText).commit()
        } catch (e: Exception) {
            clearSavedData()

        }
    }

    fun decryptString(cipherText: String): String? {

        try {
            val bytes = Base64.decode(cipherText, Base64.NO_WRAP)
            val finalText = String(mcipher!!.doFinal(bytes))
            return finalText;
        } catch (e: Exception) {

            clearSavedData()
        }
        return null;
    }


    class UserLoginTask : AsyncTask<Void, Void, Boolean> {

        private val mEmail: String?
        private val mPassword: String?
        private val mRegister: Boolean? // if false, authenticate instead
        private var biometricHelper: WeakReference<BiometricHelper>

        private var editor: WeakReference<SharedPreferences>

        internal constructor(biometricHelper: BiometricHelper,
                             editor: SharedPreferences,
                             email: String, password: String) {
            this.biometricHelper = WeakReference<BiometricHelper>(biometricHelper)
            this.editor = WeakReference<SharedPreferences>(editor)
            mEmail = email
            mPassword = password
            mRegister = true
        }

        internal constructor(biometricHelper: BiometricHelper,
                             editor: SharedPreferences) {
            this.biometricHelper = WeakReference(biometricHelper)
            this.editor = WeakReference(editor)
            mRegister = false
            mEmail = null
            mPassword = null
        }

        override fun doInBackground(vararg params: Void): Boolean? {
            if (!biometricHelper.get()!!.getKeyStore())
                return false

            if (!biometricHelper.get()!!.createNewKey(false))
                return false

            if (!biometricHelper.get()!!.getCipher())
                return false

            // Inside doInBackground
            if (mRegister!!) {
                biometricHelper.get()!!.encrypting = true

                if (!biometricHelper.get()!!.initCipher(Cipher.ENCRYPT_MODE))
                    return false
            } else {
                biometricHelper.get()!!.encrypting = false
                if (!biometricHelper.get()!!.initCipher(Cipher.DECRYPT_MODE))
                    return false
            }

            return if (!biometricHelper.get()!!.initCryptObject()) false else true

        }

        override fun onPostExecute(success: Boolean) {

            if (success && !isCancelled) {
                mRegister?.let { biometricHelper.get()!!.startAuth(it) }
            } else {
                //something not right proceed with normal login
                biometricHelper.get()!!.onFingerprintRegistrationDenied()
            }

        }
    }

    fun onFingerprintRegistrationDenied() {
        mListener.get()?.onFingerPrintRegistrationDenied()
    }


    override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
        // super.onAuthenticationError(errorCode, errString)
        Logger.d("onAuthenticationError ****  " + errorCode + "***   " + errString)
        if ((errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON || errorCode == BiometricPrompt.ERROR_USER_CANCELED) && encrypting) {
            mListener.get()?.onFingerPrintRegistrationDenied()
        } else if (errorCode == BiometricPrompt.ERROR_CANCELED || errorCode == BiometricPrompt.ERROR_LOCKOUT || errorCode == BiometricPrompt.ERROR_LOCKOUT_PERMANENT) {
            myBiometricPrompt.cancelAuthentication()
            mListener.get()?.onAuthenticationFailed(errString.toString())
        } else {
            super.onAuthenticationError(errorCode, errString)
            //    listener.onAuthenticationFailed(errString.toString())
        }
    }


    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {

        if (encrypting) {
            mPassword?.let { encryptString(it) }
            mListener.get()?.onAuthenticationSuccessful(result)
        } else {
            var encryptedPassword = mEditor.getString(PREFERENCES_KEY_PASS, "");
            val decryptedPassword = decryptString(encryptedPassword)
            if (decryptedPassword != null) {
                mListener.get()?.onSavedUserAuthenticationSuccessful(decryptedPassword)
            } else {
                mListener.get()?.onAuthenticationFailed(SignInFragment.FINGERPRINT_ERROR)
            }
        }


    }

    fun clearSavedData() {
        var localEditor = mEditor.edit()
        localEditor.remove(PREFERENCES_KEY_IV).commit();
        localEditor.remove(PREFERENCES_KEY_PASS).commit();

        try {
            mkeyStore?.deleteEntry(PrefManager.getInstance().keyAlias);

        } catch (ex: java.lang.Exception) {
        } finally {
            PrefManager.getInstance().remove(PrefManager.Key.PREF_KEY_ALIAS)
        }

    }



    fun onDestroy() {
        if (mAuthTask != null) {
            mAuthTask?.cancel(true);
            mAuthTask = null
        }
    }

}
class BiometricHelper(var localListener:BiometricHelperListener,val fragmentActivity:fragmentActivity):BiometricPrompt.AuthenticationCallback(){
private val mListener:WeakReference=WeakReference(localListener)
私有val MFFragmentActivity:WeakReference=WeakReference(碎片活动)
val mEditor:SharedReferences=PreferenceManager.GetDefaultSharedReferences(TransfasApplication.getContext())
private val TAG=BiometricHelper::class.java!!.getName()
私有变量mkeyStore:KeyStore?=null
专用var MGGenerator:KeyGenerator?=null
私有变量mcipher:密码?=null
private val KEYSTORE=“somevalue”
私人val首选项\u KEY\u IV=“somevalue”
私人val首选项\u KEY\u PASS=“somevalue”
private var mcryptoObject:BiometricPrompt.CryptoObject?=null
私有变量加密:布尔值=false
私有变量mEmail:字符串?=null
私有变量mPassword:字符串?=null
private var mAuthTask:BiometricHelper.UserLoginTask?=null
private lateinit var myBiometricPrompt:生物特征提示
接口帮助列表器{
验证成功(结果:BiometricPrompt.AuthenticationResult)
fun onSavedUserAuthenticationSuccessful(密码:字符串)
验证失败(错误:字符串)
fun onFingerPrintRegistrationDenied()
NobiometricsSupport()的乐趣
}
public fun registerAuthentication(电子邮件:字符串,密码:字符串){
this.mEmail=电子邮件;
this.mPassword=密码;
mAuthTask=UserLoginTask(此、mEditor、电子邮件、密码)
mAuthTask?执行(空为空?)
}
public fun authenticateExistingUser(电子邮件:String){
this.mEmail=电子邮件
mAuthTask=UserLoginTask(此,mEditor);
mAuthTask?执行(空为空?)
}
私人娱乐startAuth(isRegister:Boolean){
val executor=Executors.newSingleThreadExecutor()
myBiometricPrompt=BiometricPrompt(MFFragmentActivity.get()!!,执行者,此)
if(mcryptoObject!=null){
if(isRegister){
val promptInfo=prompt.promptInfo.Builder()
.setTitle(“启用指纹”)
.setSubtitle(MFFragmentActivity.get()!!.resources.getString(R.string.fingerprint\u confirm\u message))
//.setDescription(MFFragmentActivity.get()!!.resources.getString(R.string.fingerprint\u confirm\u description))
.setNegativeButtonText(MFFragmentActivity.get()!!.resources.getString(R.string.text_cancel))
.build()
myBiometricPrompt.authenticate(PrompInfo,mcryptoObject!!)
}否则{
val promptInfo=prompt.promptInfo.Builder()
.setTitle(“登录”)
.setSubtitle(mEmail)
.setNegativeButtonText(MFFragmentActivity.get()!!.resources.getString(R.string.text_cancel))
.build()
myBiometricPrompt.authenticate(PrompInfo,mcryptoObject!!)
}
}
}
public fun isUserRegistered():布尔值{
if(mEditor.getString(首选项\键\传递,null)!=null){
返回true;
}
返回false;
}
公共支持():布尔值{
if(Build.VERSION.SDK_INT