首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Digital persona SDK -本机问题

Digital persona SDK -本机问题
EN

Stack Overflow用户
提问于 2020-04-27 00:22:23
回答 1查看 209关注 0票数 0

我在我的应用程序中使用Digital Persona SDK进行指纹识别。当我在少于250个fmds上使用identify功能时,它工作正常。

代码语言:javascript
复制
Engine.Candidate candidates[] = m_engine.Identify(searchedFmd, 0, fmdArray, DEFAULT_THRESHOLD, 1); //fmdArray < 250

但是当fmdArray > 250时,它会给我一个本机运行时错误:

代码语言:javascript
复制
A/art: art/runtime/indirect_reference_table.cc:132] JNI ERROR (app bug): local reference table overflow (max=512)

现在,我在几个安卓设备上运行了这个应用程序,得出的结论是,我的应用程序在安卓7上运行时,fmdArray > 250,但安卓8运行得很好。在8中,我甚至可以对4000个fmds进行检查,它工作得很好。

但我需要在运行android 7的特定设备上运行这段代码。

我试着只在两个250个fmds的线程中运行它。但是在单次运行之后,SDK还有另一个问题。在第二次运行时,它不工作。

这就是我要做的:首先,我得到一个我想要识别的指纹:

代码语言:javascript
复制
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代码中工作?或者至少解决方案的方向是什么?

EN

回答 1

Stack Overflow用户

发布于 2020-04-27 14:47:10

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61444137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档