【发布时间】:2013-08-24 19:10:36
【问题描述】:
我正在编写一个 Android 应用程序,它正在打开一个本地存储的 html 文件 check.html。这个 html 文件显示了一些不错的文本,然后 http 转发到我真正想要的网页。现在可能会发生服务器已关闭,甚至网络已断开,但我希望应用程序一直尝试访问它。
如果只是服务器宕机,Android在返回onReceivedError()之前请求网页时会有一些延迟,所以我没有问题,但是如果网络被拔掉,它会立即返回。
1 到 2 分钟后,我的应用崩溃了:
08-22 14:17:47.382: D/dalvikvm(8337): GC_CONCURRENT 释放 178K,3% 释放 12530K/12807K,暂停 0ms+7ms
08-22 14:17:57.572: D/dalvikvm(8337): GC_CONCURRENT 释放 235K,3% 释放 14253K/14599K,暂停 0ms+7ms
08-22 14:18:07.882: D/dalvikvm(8337): GC_CONCURRENT 释放 241K,3% 释放 15969K/16327K,暂停 0ms+10ms
08-22 14:18:17.717: D/dalvikvm(8337): GC_CONCURRENT 释放 237K,2% 释放 17717K/18055K,暂停 0ms+13ms
08-22 14:18:28.757: D/dalvikvm(8337): GC_CONCURRENT 释放 249K,2% 释放 19468K/19783K,暂停 3ms+3ms
08-22 14:18:39.105: D/dalvikvm(8337): GC_CONCURRENT 释放 241K,2% 释放 21185K/21511K,暂停 4ms+10ms
08-22 14:18:49.008: D/dalvikvm(8337): GC_CONCURRENT 释放 238K,2% 释放 22900K/23239K,暂停 0ms+10ms
08-22 14:18:51.157: E/dalvikvm(8337): JNI ERROR (app bug): local reference table overflow (max=512)
08-22 14:18:51.157: W/dalvikvm(8337): JNI 本地参考表 (0x1729e78) 转储:
08-22 14:18:51.157:W/dalvikvm(8337):最后 10 个条目(共 512 个):
08-22 14:18:51.157: W/dalvikvm(8337): 511: 0x410dec88 android.content.res.AssetManager
08-22 14:18:51.157: W/dalvikvm(8337): 510: 0x4215db30 byte[] (32768 个元素)
08-22 14:18:51.157: W/dalvikvm(8337): 509: 0x42155b18 byte[] (32768 个元素)
08-22 14:18:51.158: E/dalvikvm(8337): 添加到 JNI 本地引用表失败(有 512 个条目)
代码如下:
mWebView = (WebView) findViewById(R.id.webView);
mWebView.setWebChromeClient(new KB_WebChromeClient(this));
mWebView.setWebViewClient(new KB_WebViewClient());
mWebView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
mWebView.clearCache(true);
mWebView.clearHistory();
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.addJavascriptInterface(new WebAppInterface(this, this), "Android");
mWebView.loadUrl("file:///android_asset/check.html");
WebViewClient 的代码如下:
public class KB_WebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.clearCache(true);
}
@Override
public void onReceivedError (WebView view, int errorCode, String description, String failingUrl)
{
view.loadUrl("file:///android_asset/check.html");
}
}
基本上,check.html页面被加载,onPageFinished被调用,然后html转发到另一个页面,这不起作用,所以onReceivedError被调用,它将再次开始加载check.html aso .
在我的研究中我找到了SO: Android Expand JNI Local Reference Table,答案是
您需要删除对类和对象的本地引用。
这是什么意思,我的问题在哪里? webview.loadUrl 是否会创建任何复杂的东西并且垃圾收集器不够快而无法清理?我不是一直都在创建 WebView,这到底是怎么回事?
提前感谢您的帮助!
编辑:我实现了一个计数器来计算 webview.loadUrl 被调用的频率。在应用程序崩溃之前,它计数 280 到 290。我试图删除 check.html 并在网络中加载我想要的网页,然后尝试次数达到 570 次才崩溃。它接缝,每个网页加载都被计算在内,即使它是从 HTML 页面完成的。我正在查看系统的堆,我看到的是,每次完成一个循环时,都会分配 1 到 3 个 byte[] 数组,大小为 32kB,但未释放。即使是垃圾收集也没有释放它。我会尝试每 x 次尝试摆脱 Webview。也许这种解决方法可以工作......
编辑:在link 下,它们显示存在错误:
external/webkit/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp 好像有泄漏。
如果 (!m_buffer) {
m_buffer = env->NewByteArray(out->capacity());
m_buffer = (jbyteArray) env->NewGlobalRef(m_buffer);
}
本地引用由 NewByteArray 创建,但不会被删除。
我认为这可能与我的问题有关。我正在运行 Android 4.0.3 并且无法更新,因为他们似乎解决了这个问题....好吧,我会尝试找到解决方法。
【问题讨论】:
标签: java android memory webview java-native-interface