项目背景:指纹支付中获取IFAA设备ID,部分厂商系统升级之后会出现获取ID超时现象,在没做判空处理的情况下产品会全线崩溃。
方案:在项目启动的时候进行IFAA初始化。
/**
* 初始化ifaaDeviceId,存入缓存
*
* @param typeFingerprint
*/
public static void initIfaaDeviceIdByType(int typeFingerprint) {
long startTime = System.currentTimeMillis();
LogUtils.d(TAG, "initIfaaDeviceIdByType start type:" + typeFingerprint);
if (authenticator == null) {
authenticator = AuthenticatorManager.create(PayKernelApplication.getInstance(), typeFingerprint, appName);
}
//底层抛null
if (authenticator == null) {
ifaaDeviceId = "";
isSupportIfaaDeviceId = false;
sendIfaaNetLog(startTime, "创建authenticator失败");
return;
}
if (!authenticator.isSupported()
|| !authenticator.hasEnrolled()) {
ifaaDeviceId = "";
isSupportIfaaDeviceId = false;
sendIfaaNetLog(startTime, "不支持IFAA");
return;
}
String log = "";
executor = (Executor) Executors.newCachedThreadPool();
mTask = new IfaaSdkDeviceIdTask(authenticator);
try {
mTask.executeOnExecutor(executor);
ifaaDeviceId = mTask.get(TIME_OUT, TimeUnit.MILLISECONDS);
if (TextUtils.isEmpty(ifaaDeviceId)) {
isSupportIfaaDeviceId = false;
log = "initIfaaDeviceIdByType调取失败ifaaDeviceId为空" + ifaaDeviceId;
} else {
isSupportIfaaDeviceId = true;
log = "initIfaaDeviceIdByType调取成功ifaaDeviceId:" + ifaaDeviceId;
}
} catch (InterruptedException e) {
ifaaDeviceId = "";
isSupportIfaaDeviceId = false;
log = "initIfaaDeviceIdByType调取InterruptedException";
authenticator.cancel();
} catch (ExecutionException e) {
ifaaDeviceId = "";
isSupportIfaaDeviceId = false;
log = "initIfaaDeviceIdByType调取ExecutionException";
authenticator.cancel();
} catch (TimeoutException e) {
ifaaDeviceId = "";
isSupportIfaaDeviceId = false;
log = "initIfaaDeviceIdByType调取超时";
authenticator.cancel();
}
LogUtils.d(TAG, log);
}
public class IfaaSdkDeviceIdTask extends AsyncTask<Void, Void, String> {
private IAuthenticator mIAuthenticator;
public IfaaSdkDeviceIdTask(IAuthenticator iAuthenticator) {
this.mIAuthenticator = iAuthenticator;
}
@Override
protected String doInBackground(Void... params) {
String deviceId = null;
if (mIAuthenticator != null) {
//获取ifaa的DeviceId
deviceId = mIAuthenticator.getDeviceId();
}
//返回DeviceId
return deviceId;
}
@Override
protected void onPostExecute(String result) {
}
}
细节:mTask.get()方法是超时判断方法,如果在规定时间异步线程没有完成的情况下直接会有超时异常,但是原有的线程会继续运行,所以需要在超时处理中中断获取deviceId的操作,mTask.get()获取的结果就是doInBackground返回的结果,所以onPostExecute中不需要再次对结果进行处理,否则会出现二次处理的逻辑混乱。