Post

问题整理二

对于WebView来讲,不要直接在xml中使用,因为这样,在Activity销毁的时候,内存也不会被释放,一些值得去做的方法:

1
2
3
4
5
6
7
8
9
//使用ApplicationContext初始化
WebView webView = new WebView(getApplicationContext());
//如果在 fragment 里面
@Override
public void onDetach(){
    super.onDetach();
    webView.removeAllViews();
    webView.destroy();
}
1
2
3
4
5
6
7
8
9
10
11
12
//清单文件中统一管理进程
<application
    android:process="com.processkill.p1">
    <activity
        android:name="com.processkill.A"
        android:process="com.processkill.p2">
    </activity>
    <activity
        android:name="com.processkill.B"
        android:process="com.processkill.p3">
    </activity>
</application>

Romain Guy写过这样一个文章avoid-memory-leaks-on-android.当然现在看起来有些过时了,现在会在设置第二次的时候检查并释放前一个引用,当然我们应该避免这样使用 static 关键字

1
2
3
4
5
6
7
8
/*
 * Regardless of whether we're setting a new background or not, we want
 * to clear the previous drawable.
 */
if (mBackground != null) {
    mBackground.setCallback(null);
    unscheduleDrawable(mBackground);
}

WebView加载中在链接上添加参数,需要注意的是要对参数编码,以前可能使用的是NameValuePair,API 23以后会提示@deprecated,其实这里根据自己的喜好习惯可以自己去操作,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 JSONObject json = new JSONObject();
 Iterator<String> keys = json.keys();
 StringBuilder stringBuilder = new StringBuilder();
 try {
     while (keys.hasNext()) {
         String key = keys.next();
         String value = json.optString(key);
         if (value != null) {
             stringBuilder.append(URLEncoder.encode(key, "UTF-8"))
                     .append("=")
                     .append(URLEncoder.encode(value, "UTF-8"));
         }
     }
 } catch (UnsupportedEncodingException e) {
     e.printStackTrace();
 }

本质还是一样的,原来的使用方式中,会有两次 toString的操作,也是类似的操作,具体不写了

WebView设置 Cookies的过程中无效

以前直接使用的android.webkit.CookieManager,现在使用OkHttpClient的时候就得自己同步一下Cookies,抓包看了半天确实没有 Cookies,研究了一下文档才知道哪里问题,简略的记录一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Uri uri = API.getUri();

HttpUrl httpUrl = new HttpUrl.Builder()
        .scheme(uri.getScheme())
        .host(uri.getHost())
        .build();

OkHttpClient okHttpClient = ClientManager.getInstance();
CookieJar cookieJar = okHttpClient.cookieJar();

List<Cookie> cookies = cookieJar.loadForRequest(httpUrl);

for (Cookie cookie : cookies) {
    if (cookie != null) {
        String cookieString = cookie.name() + "=" + cookie.value() + "; domain=" + cookie.domain();
        cookieManager.setCookie(httpUrl.toString(), cookieString);
    }
}

重点就是,接收的参数竟然是 URL 而不是 Host

1
2
3
4
5
6
7
8
9
10
/**
 * Sets a cookie for the given URL. Any existing cookie with the same host,
 * path and name will be replaced with the new cookie. The cookie being set
 * will be ignored if it is expired.
 *
 * @param url the URL for which the cookie is to be set
 * @param value the cookie as a string, using the format of the 'Set-Cookie'
 *              HTTP response header
 */
public abstract void setCookie(String url, String value);
This post is licensed under CC BY 4.0 by the author.