这是WebView的子类,它使用上述技巧无缝地避免内存泄漏:
package com.mycompany.view;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.AttributeSet;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class NonLeakingWebView extends WebView {
private static Field sConfigCallback;
static {
try {
sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback");
sConfigCallback.setAccessible(true);
} catch (Exception e) {
}
}
public NonLeakingWebView(Context context) {
super(context.getApplicationContext());
setWebViewClient( new MyWebViewClient((Activity)context) );
}
public NonLeakingWebView(Context context, AttributeSet attrs) {
super(context.getApplicationContext(), attrs);
setWebViewClient(new MyWebViewClient((Activity)context));
}
public NonLeakingWebView(Context context, AttributeSet attrs, int defStyle) {
super(context.getApplicationContext(), attrs, defStyle);
setWebViewClient(new MyWebViewClient((Activity)context));
}
@Override
public void destroy() {
super.destroy();
try {
if( sConfigCallback!=null )
sConfigCallback.set(null, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected static class MyWebViewClient extends WebViewClient {
protected WeakReference<Activity> activityRef;
public MyWebViewClient( Activity activity ) {
this.activityRef = new WeakReference<Activity>(activity);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try {
final Activity activity = activityRef.get();
if( activity!=null )
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}catch( RuntimeException ignored ) {
}
return true;
}
}
}
要使用它,只需在布局中将WebView替换为NonLeakingWebView
<com.mycompany.view.NonLeakingWebView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
...
/>
然后确保NonLeakingWebView.destroy()
从您活动的onDestroy方法进行调用。
请注意,此Web客户端应处理常见情况,但功能可能不如常规Web客户端那么全。例如,我还没有针对Flash等进行过测试。