每次我测试我的应用程序时,我都会在我的logcat中收到一次此警告.
W A resource failed to call close.
我使用了在onCreate()
方法中在线找到的以下代码来引发异常和堆栈跟踪,以找出导致异常的原因.
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy()).detectLeakedClosableObjects().build());
这产生了以下堆栈跟踪.
StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:1994)
at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:336)
at java.io.FileInputStream.finalize(FileInputStream.java:508)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:339)
at java.lang.Daemons$FinalizerDaemon.processReference(Daemons.java:324)
at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:300)
at java.lang.Daemons$Daemon.run(Daemons.java:145)
at java.lang.Thread.run(Thread.java:1012)
Caused by: java.lang.Throwable: Explicit termination method 'close' not called
at dalvik.system.CloseGuard.openWithCallSite(CloseGuard.java:288)
at dalvik.system.CloseGuard.open(CloseGuard.java:257)
at java.io.FileInputStream.<init>(FileInputStream.java:176)
at edu.cmu.pocketsphinx.Assets.getExternalItems(Assets.java:149)
at edu.cmu.pocketsphinx.Assets.syncAssets(Assets.java:253)
at com.example.atest.MainActivity$SetupTask.doInBackground(MainActivity.java:127)
at com.example.atest.MainActivity$SetupTask.doInBackground(MainActivity.java:118)
at android.os.AsyncTask$3.call(AsyncTask.java:394)
at java.util.concurrent.FutureTask.run(FutureTask.java:264)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at java.lang.Thread.run(Thread.java:1012)
我追溯到这个代码..
private static class SetupTask extends AsyncTask<Void, Void, Exception> {
WeakReference<MainActivity> activityReference;
SetupTask(MainActivity activity) {
this.activityReference = new WeakReference<>(activity);
}
@Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(activityReference.get());
File assetDir = assets.syncAssets();
activityReference.get().setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
@Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) activityReference.get().findViewById(R.id.status_text)).setText(R.string.status_fail);
Log.d(TAG, "SetupTask: Exception: " + result.getMessage());
// TODO: decide what to do when there is an exception
} else {
Log.d(TAG, "SetupTask: startSearch()");
activityReference.get().startSearch();
}
}
}
这是我从pocketphinsx-android获得的代码. 设置Asset和语音识别器需要时间,因此他们建议在Asmat任务中执行,以防止主线程上丢失帧. 我可以做一些明显的事情来消除这个警告吗? 我在下面测试了此代码的同步版本,并生成了相同的堆栈跟踪.
try {
Assets assets = new Assets(this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
startSearch();
} catch (IOException e) {
Log.d(TAG, e.getMessage());
}
我已经把它进一步钉在..
File assetDir = assets.syncAssets();
因为我把它改成了..
File assetDir = assets.getExternalDir()
而且我没有收到任何警告. 似乎是一个袖珍狮身电脑的问题.