我正在编写一个打开本地存储的 html 文件的 Android 应用程序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% free 14253K/14599K, paused 0ms+7ms
08-22 14:18:07.882: D/dalvikvm(8337): GC_CONCURRENT freed 241K, 3% free 15969K/16327K, paused 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/19 , 暂停 3ms+3ms
08-22 14:18:39.105: D/dalvikvm(8337): GC_CONCURRENT freed 241K, 2% free 21185K/21511K, paused 4ms+10ms
08-22 14:18:49.008: D/dalvikvm(8337 ): GC_CONCURRENT freed 238K, 2% free 22900K/23239K, paused 0ms+10ms
08-22 14:18:51.157:E/dalvikvm(8337):JNI 错误(应用程序错误):本地引用表溢出(最大值 = 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。
在我的研究中,我发现了:Android Expand JNI Local Reference Table,答案是
您需要删除对类和对象的本地引用。
这是什么意思,我的问题在哪里?webview.loadUrl 是否会创建任何复杂的东西并且垃圾收集器不够快而无法清理?我不是一直都在创建 WebView,那么到底有什么问题呢?
提前感谢您的帮助!
编辑:我实现了一个计数器,它计算 webview.loadUrl 被调用的频率。在应用程序崩溃之前,它计数 280 到 290。我试图删除check.html
并在网络中加载我想要的网页,然后在崩溃之前尝试次数上升到 570。它接缝,每个网页加载都被计算在内,即使它是从 HTML 页面完成的。我正在查看系统的堆,我看到的是,每次完成一个循环时,都会分配 1 到 3 个 byte[] 数组,大小为 32kB,但未释放。即使是垃圾收集也没有释放它。我会尝试每 x 次尝试摆脱 Webview。也许这种解决方法可以工作......
编辑:在他们显示存在错误的链接下:
好像external/webkit/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp有泄漏。
if (!m_buffer) {
m_buffer = env->NewByteArray(out->capacity());
m_buffer = (jbyteArray) env->NewGlobalRef(m_buffer); 本地引用由 NewByteArray 创建,但不会被删除
。
我认为这可能与我的问题有关。我正在运行 Android 4.0.3 并且无法更新,因为他们似乎解决了这个问题....好吧,我会尝试找到解决方法。