Android webview cookie在一段时间后被清除/垃圾收集 - 我可以设置cookie自定义存储路径吗?
问题描述:
我想让我的webview记住它的cookies。我的问题是,他们在一段时间后被删除。Android webview cookie在一段时间后被清除/垃圾收集 - 我可以设置cookie自定义存储路径吗?
经过一番研究,我发现java的内部HttpClient使用CookieManager和CookieStore会得到垃圾回收。 HttpClient用于我的一些网络代码(并非全部由我编写)。 我很确定这是我的问题的原因。
所以我的问题是:有没有办法将cookie从webview保存到另一个位置比由HttpClient使用的位置?
我已经尝试设置像这样的自定义路径:
webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
if (getCustomActivity() != null) {
CookieSyncManager.createInstance(getCustomActivity()).sync();
}
}
});
webview.getSettings().setAppCachePath("/data/data/"+getActivity().getPackageName()+"/webview_cookies/");
webview.loadUrl(url, true);
,但没有运气。
我真的很希望有人能帮助我。 任何帮助将不胜感激。
答
我终于找到了一个解决方案,我很满意。基本上,我将Cookie保存在共享首选项中并从那里获取它们。
这里是我的解决方案建议(扩大AdvancedWebView,这也可能是标准的WebView视图类):
public class PersistentCookiesWebView extends AdvancedWebView {
private static String url = "PersistentCookiesWebView";
private static String cookieKey = "";
private static final String COOKIE_STORAGE_KEY_PREFIX = "cskp_";
private static final long COOKIE_MAX_STORAGE_BYTES = 500000;
public PersistentCookiesWebView(Context context) {
super(context);
}
public PersistentCookiesWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PersistentCookiesWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void loadUrl(final String url, String cookieKey) {
this.url = url;
this.cookieKey = cookieKey;
initializeWebView(new WebViewListener() {
@Override
public void onWebViewReady() {
PersistentCookiesWebView.super.loadUrl(url);
}
});
}
@Override
public void loadUrl(final String url) {
this.url = url;
this.cookieKey = getHostName();
initializeWebView(new WebViewListener() {
@Override
public void onWebViewReady() {
PersistentCookiesWebView.super.loadUrl(url);
}
});
}
@Override
public void loadUrl(final String url, final Map<String, String> additionalHttpHeaders) {
this.url = url;
this.cookieKey = getHostName();
initializeWebView(new WebViewListener() {
@Override
public void onWebViewReady() {
PersistentCookiesWebView.super.loadUrl(url, additionalHttpHeaders);
}
});
}
@Override
public void loadUrl(final String url, final boolean preventCaching) {
this.url = url;
this.cookieKey = getHostName();
initializeWebView(new WebViewListener() {
@Override
public void onWebViewReady() {
PersistentCookiesWebView.super.loadUrl(url, preventCaching);
}
});
}
@Override
public void loadUrl(final String url, final boolean preventCaching, final Map<String, String> additionalHttpHeaders) {
this.url = url;
this.cookieKey = getHostName();
initializeWebView(new WebViewListener() {
@Override
public void onWebViewReady() {
PersistentCookiesWebView.super.loadUrl(url, preventCaching, additionalHttpHeaders);
}
});
}
protected void initializeWebView(final WebViewListener webViewListener) {
setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
CookieManager.getInstance().flush();
}
});
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
saveCookies(null);
return false;
}
});
fetchCookies(new CookieFetchListener() {
@Override
public void onCookiesFetched() {
webViewListener.onWebViewReady();
}
});
}
public void saveCookies(CookieSaveListener cookieSaveListener) {
String storageKey = COOKIE_STORAGE_KEY_PREFIX + cookieKey;
String currentCookieString = CookieManager.getInstance().getCookie(url) + "";
ArrayList<String> currentCookieList = new ArrayList<String>(Arrays.asList(currentCookieString.split(";")));
long cookieBytes = 0;
String newCookies = "";
for(int i = currentCookieList.size() - 1; i >= 0; i--) {
String cookie = currentCookieList.get(i);
try {
cookieBytes = cookieBytes + cookie.getBytes().length;
} catch (Exception e) {
e.printStackTrace();
}
if (cookieBytes < COOKIE_MAX_STORAGE_BYTES) {
newCookies = cookie + ";" + newCookies;
} else {
break;
}
}
PreferencesManager.putString(getContext(), storageKey, newCookies);
if (cookieSaveListener != null) {
cookieSaveListener.onCookiesSaved();
}
}
private void fetchCookies(final CookieFetchListener cookieFetchListener) {
String storageKey = COOKIE_STORAGE_KEY_PREFIX + cookieKey;
String currentCookieString = CookieManager.getInstance().getCookie(url) + "";
String storedCookiesString = PreferencesManager.getString(getContext(), storageKey) + "";
ArrayList<String> storedCookiesList = new ArrayList<String>(Arrays.asList(storedCookiesString.split(";")));
for (String storedCookie : storedCookiesList) {
if(!currentCookieString.contains(storedCookie)) {
CookieManager.getInstance().setCookie(url, storedCookie);
CookieManager.getInstance().setCookie(cookieKey, storedCookie);
}
}
cookieFetchListener.onCookiesFetched();
saveCookies(null);
}
private String getHostName() {
try {
URL aURL = new URL(url);
return aURL.getHost() + "";
} catch (MalformedURLException e) {
e.printStackTrace();
return "";
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.d(getClass().getSimpleName(), "Cookies attempting to save...");
saveCookies(new CookieSaveListener() {
@Override
public void onCookiesSaved() {
Log.d(getClass().getSimpleName(), "Cookies saved!");
}
});
}
interface CookieFetchListener {
void onCookiesFetched();
}
interface CookieSaveListener {
void onCookiesSaved();
}
interface WebViewListener {
void onWebViewReady();
}
}
我希望这可以给别人有用的。
可能的重复[如何在Android web浏览器中永久保存cookie?](https://*.com/questions/8390156/how-to-save-a-cookie-in-an-android-webview-永远) –