0

我想让我的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); 

,但没有运气。

我真的很希望有人能帮助我。 任何帮助将不胜感激。

+0

可能的重复[如何在Android web浏览器中永久保存cookie?](https://stackoverflow.com/questions/8390156/how-to-save-a-cookie-in-an-android-webview-永远) –

回答

0

我终于找到了一个解决方案,我很满意。基本上,我将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(); 
    } 
} 

我希望这可以给别人有用的。