如何在 xamarin 移动应用程序中未调用 Looper.prepare() 的线程内创建处理程序
How to create handler inside thread that has not called Looper.prepare() in xamarin mobile app
我有一个具有指纹认证的移动应用程序,它使用 xamarin 框架。到目前为止,一切都适用于除三星 Note 8 之外的所有设备。在尝试调试此设备时,它给了我一个异常 Java.Lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序。我不知道它是什么意思以及如何修复它,因为它适用于其他设备。它在行上给出异常
keyGen.Init(keyGenSpec)
static readonly string KEY_NAME = "YYYYYYY";
static readonly string KEYSTORE_NAME = "AndroidKeyStore";
static readonly string KEY_ALGORITHM = KeyProperties.KeyAlgorithmAes;
static readonly string BLOCK_MODE = KeyProperties.BlockModeCbc;
static readonly string ENCRYPTION_PADDING = KeyProperties.EncryptionPaddingPkcs7;
static readonly string TRANSFORMATION = KEY_ALGORITHM + "/" +
BLOCK_MODE + "/" +
ENCRYPTION_PADDING;
readonly KeyStore _keystore;
public CryptoObjectHelper()
{
_keystore = KeyStore.GetInstance(KEYSTORE_NAME);
_keystore.Load(null);
}
public FingerprintManagerCompat.CryptoObject BuildCryptoObject()
{
Cipher cipher = CreateCipher();
return new FingerprintManagerCompat.CryptoObject(cipher);
}
Cipher CreateCipher(bool retry = true)
{
IKey key = GetKey();
Cipher cipher = Cipher.GetInstance(TRANSFORMATION);
try
{
cipher.Init(CipherMode.EncryptMode, key);
}
catch (KeyPermanentlyInvalidatedException e)
{
_keystore.DeleteEntry(KEY_NAME);
if (retry)
{
CreateCipher(false);
}
else
{
throw new Exception("Could not create the cipher for fingerprint authentication.", e);
}
}
return cipher;
}
IKey GetKey()
{
if (!_keystore.IsKeyEntry(KEY_NAME))
{
CreateKey();
}
IKey secretKey = _keystore.GetKey(KEY_NAME, null);
return secretKey;
}
void CreateKey()
{
KeyGenerator keyGen = KeyGenerator.GetInstance(KeyProperties.KeyAlgorithmAes, KEYSTORE_NAME);
KeyGenParameterSpec keyGenSpec =
new KeyGenParameterSpec.Builder(KEY_NAME, KeyStorePurpose.Encrypt | KeyStorePurpose.Decrypt)
.SetBlockModes(BLOCK_MODE)
.SetEncryptionPaddings(ENCRYPTION_PADDING)
.SetUserAuthenticationRequired(true)
.Build();
keyGen.Init(keyGenSpec);
keyGen.GenerateKey();
}
如果不查看更多代码,很难判断发生了什么。看来您的代码是在后台线程上执行的。您可以尝试添加 android.os.Looper.Prepare()
作为 CreateKey()
中的第一行。希望有用。
I have no idea what does it mean and how to fix it because it works well with other devices. It gives exception on row keyGen.Init(keyGenSpec)
这是一个类似的问题here。按照建议,您可以捕获异常并根据 failedOnNote8
:
在 UI 线程上初始化密钥
failedOnNote8=false;
try{
keyGen.Init(keyGenSpec);
}catch (Exception e) {
if(e.getMessage() != null && e.getMessage().equals("Can't create handler inside thread that has not called Looper.prepare()")) {
failedOnNote8 = true;
}
}
if(failedOnNote8)
{
//try to init the key on UI Thread.
}
我有一个具有指纹认证的移动应用程序,它使用 xamarin 框架。到目前为止,一切都适用于除三星 Note 8 之外的所有设备。在尝试调试此设备时,它给了我一个异常 Java.Lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序。我不知道它是什么意思以及如何修复它,因为它适用于其他设备。它在行上给出异常 keyGen.Init(keyGenSpec)
static readonly string KEY_NAME = "YYYYYYY";
static readonly string KEYSTORE_NAME = "AndroidKeyStore";
static readonly string KEY_ALGORITHM = KeyProperties.KeyAlgorithmAes;
static readonly string BLOCK_MODE = KeyProperties.BlockModeCbc;
static readonly string ENCRYPTION_PADDING = KeyProperties.EncryptionPaddingPkcs7;
static readonly string TRANSFORMATION = KEY_ALGORITHM + "/" +
BLOCK_MODE + "/" +
ENCRYPTION_PADDING;
readonly KeyStore _keystore;
public CryptoObjectHelper()
{
_keystore = KeyStore.GetInstance(KEYSTORE_NAME);
_keystore.Load(null);
}
public FingerprintManagerCompat.CryptoObject BuildCryptoObject()
{
Cipher cipher = CreateCipher();
return new FingerprintManagerCompat.CryptoObject(cipher);
}
Cipher CreateCipher(bool retry = true)
{
IKey key = GetKey();
Cipher cipher = Cipher.GetInstance(TRANSFORMATION);
try
{
cipher.Init(CipherMode.EncryptMode, key);
}
catch (KeyPermanentlyInvalidatedException e)
{
_keystore.DeleteEntry(KEY_NAME);
if (retry)
{
CreateCipher(false);
}
else
{
throw new Exception("Could not create the cipher for fingerprint authentication.", e);
}
}
return cipher;
}
IKey GetKey()
{
if (!_keystore.IsKeyEntry(KEY_NAME))
{
CreateKey();
}
IKey secretKey = _keystore.GetKey(KEY_NAME, null);
return secretKey;
}
void CreateKey()
{
KeyGenerator keyGen = KeyGenerator.GetInstance(KeyProperties.KeyAlgorithmAes, KEYSTORE_NAME);
KeyGenParameterSpec keyGenSpec =
new KeyGenParameterSpec.Builder(KEY_NAME, KeyStorePurpose.Encrypt | KeyStorePurpose.Decrypt)
.SetBlockModes(BLOCK_MODE)
.SetEncryptionPaddings(ENCRYPTION_PADDING)
.SetUserAuthenticationRequired(true)
.Build();
keyGen.Init(keyGenSpec);
keyGen.GenerateKey();
}
如果不查看更多代码,很难判断发生了什么。看来您的代码是在后台线程上执行的。您可以尝试添加 android.os.Looper.Prepare()
作为 CreateKey()
中的第一行。希望有用。
I have no idea what does it mean and how to fix it because it works well with other devices. It gives exception on row keyGen.Init(keyGenSpec)
这是一个类似的问题here。按照建议,您可以捕获异常并根据 failedOnNote8
:
failedOnNote8=false;
try{
keyGen.Init(keyGenSpec);
}catch (Exception e) {
if(e.getMessage() != null && e.getMessage().equals("Can't create handler inside thread that has not called Looper.prepare()")) {
failedOnNote8 = true;
}
}
if(failedOnNote8)
{
//try to init the key on UI Thread.
}