数字角色SDK-本机问题



我正在我的应用程序中使用Digital Persona SDK进行指纹识别。当我在不到250个fmd上使用identify函数时,它工作得很好。

Engine.Candidate candidates[] = m_engine.Identify(searchedFmd, 0, fmdArray, DEFAULT_THRESHOLD, 1); //fmdArray < 250

但是fmdArray>250给了我一个本地运行时错误:

A/art: art/runtime/indirect_reference_table.cc:132] JNI ERROR (app bug): local reference table overflow (max=512)

现在我在几个安卓设备上运行了这个应用程序,得出的结论是,当我的应用程序在安卓7上运行时,fmdArray>250会崩溃。但android 8运行良好。在8中,我甚至可以在4000个fmd上预成型一张支票,而且效果很好。

但我需要在运行android 7的特定设备中运行此代码。

我试着只在250个fmd的几个线程中运行它。但是在单次运行之后,SDK又出现了另一个问题。第二次运行时,它不起作用。

我就是这样做的:首先,我得到了一个指纹捕获,我想识别:

Reader.CaptureResult capture = m_reader.Capture(fidFormat, UrUSDK.DefaultImageProcessing, m_DPI, timeout);
// In second run, code after this line is not executed.
// My guees its not coming back from native. No exeptions. No errors.
...
Fmd scannedFmd = m_engine.CreateFmd(capture.image, fmdFormat);
...
int index = identifyFinger(fmds, scannedFmd);
...
private int identifyFinger(List<Fmd> fmdSearchArray, Fmd scannedFmd) {
List<List<Fmd>> lists = splitToChunks(fmdSearchArray);
AtomicInteger index = new AtomicInteger(-1);
List<Callable<Void>> threads = new ArrayList<>(lists.size());
AtomicInteger iteratorIndex = new AtomicInteger(0);
for (int i = 0; i < lists.size(); i++) {
int currentChunk = i;
Callable<Void> thread = () -> {
System.out.println(Thread.currentThread().getName() + " with chunk: " + iteratorIndex.getAndIncrement());
Fmd[] fmds = lists.get(currentChunk).toArray(new Fmd[IDENTIFY_BOUNDARY]);
try {
Engine.Candidate[] candidates = m_engine.Identify(scannedFmd, 0, fmds, threshold, 1);
if (candidates.length > 0) {
index.set(candidates[0].fmd_index + (currentChunk * IDENTIFY_BOUNDARY));
}
} catch (UareUException e) {
}
System.out.println(Thread.currentThread().getName() + " with chunk: " + currentChunk + " finished!");
return null;
};
threads.add(thread);
}
try {
List<Future<Void>> futures = executorService.invokeAll(threads);
System.out.println("All threads finished: " + index.get());
return index.get();
} catch (InterruptedException e) {
e.printStackTrace();
return -1;
}
}
...
private List<List<Fmd>> splitToChunks(List<Fmd> fmdSearchArray) {
int size = fmdSearchArray.size();
List<List<Fmd>> lists;
if (size > IDENTIFY_BOUNDARY) {
int chunks = size / IDENTIFY_BOUNDARY;
if (size % IDENTIFY_BOUNDARY > 0) {
chunks++;
}
lists = new ArrayList<>(chunks);
for (int i = 0; i < chunks; i++) {
if (i + 1 == chunks) {
lists.add(new ArrayList<>(fmdSearchArray.subList(i * IDENTIFY_BOUNDARY, size)));
break;
}
lists.add(new ArrayList<>(fmdSearchArray.subList(i * IDENTIFY_BOUNDARY, (i + 1) * IDENTIFY_BOUNDARY)));
}
} else {
lists = new ArrayList<>(1);
lists.add(fmdSearchArray);
}
return lists;
}

这个代码的问题在于它只运行一次。但在另一次尝试中,它并没有从Caprture调用的本地代码中返回。

所以我的问题是:我如何克服这一点,并使其在我的java代码中工作?或者至少解决方案的方向是什么?

根本原因是此Identify函数在将其推送到结果数组后,每个返回的Candidate至少保留两个引用。相反,它应该在推送后释放引用,这样它对(有限的(本地引用表的使用就保持不变。你应该为此提交一个bug。

目前最简单的解决方法是将fmdArray切成250大小的块,并为每个块调用Identify

相关内容

  • 没有找到相关文章

最新更新