cookie加載不正確的問題

華爲系統更新後安裝了一個谷歌6月安全補丁的東西,然後之前寫的調h5頁面的部分就出現了問題,後臺查過發現是Android端調h5頁面時cookie沒能帶過去,導致了登錄失敗。於是對setCookie部分的代碼進行了調試,發現單步運行時只要在setCookie部分時多等一會頁面就可以正常打開,所以懷疑是異步的問題,先是在網上查了一通,說是這種情況可以讓程序多睡會,但是這種解決方法並沒有成功,而且覺得這麼寫代碼有點彆扭,於是就又查了一下設置Cookie部分的官方說明,發現 cookieManager.removeAllCookies其實是異步函數,之前寫代碼的人把他當同步用了,導致setCookie完成後,removeAllCookies函數才執行完的,把填進去的cookie又給移除了,所以導致了打開頁面的失敗。沒安補丁之前,可能是cookie都帶過去了,remove函數才執行完,安補丁後remov函數的運行速度提升了,但是具體原因不明,因爲查不到補丁的內容,總之無論如何,異步函數當同步使用是萬萬不能的。

以下是改之前錯誤的代碼,removeAllCookies被當成了同步函數使用

   void fun(){
        ...
        addCookies();
        mWebview = (SystemWebView) appView.getView();
        engine = (SystemWebViewEngine) appView.getEngine();
        mWebview.setWebViewClient(new SystemWebViewClient(engine){
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

           ...
        });
    }


    private void addCookies() {
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
        cookieManager.setAcceptCookie(true);
        List<Cookie> cookieList = MainApp.getInstance().getGlobalState().getCookies();
        for (Cookie cookie: cookieList){
            String cookieString = cookie.name() + "=" + cookie.value();
            cookieManager.setCookie(url, cookieString);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            cookieManager.flush();
        } else {
            CookieSyncManager.createInstance(this);
            CookieSyncManager.getInstance().sync();
        }
    }

以下是改後的代碼,removeAllCookies()有一個完成後會在當前線程調用的方法,利用他remove完成後在set就沒問題了,而且addCookie()的調用被移進了onPageStarted之前,不然,之前那麼寫的話會先完成調用onPageStarted(),後完成addCookie()的調用,cookie依然不能設置成功

 void fun(){
        mWebview = (SystemWebView) appView.getView();
        engine = (SystemWebViewEngine) appView.getEngine();
        mWebview.setWebViewClient(new SystemWebViewClient(engine){
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                addCookies();
                super.onPageStarted(view, url, favicon);
            }

           ...
        });

  }


    private void addCookies() {
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            cookieManager.removeAllCookies(new ValueCallback<Boolean>() {
                @Override
                public void onReceiveValue(Boolean value) {
                    setCookie(cookieManager);
                }
            });
        }else{
            cookieManager.removeAllCookie();
            setCookie(cookieManager);
        }
    }

    void setCookie( CookieManager cookieManager){

        List<Cookie> cookieList = MainApp.getInstance().getGlobalState().getCookies();
        for (Cookie cookie: cookieList){
            String cookieString = cookie.name() + "=" + cookie.value();
            cookieManager.setCookie(url, cookieString);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            cookieManager.flush();
        } else {
            CookieSyncManager.createInstance(this);
            CookieSyncManager.getInstance().sync();
        }
    }

 這是removeAllCookies()方法的完整說明

/**
 * Removes all cookies.
 * <p>
 * This method is asynchronous.
 * If a {@link ValueCallback} is provided,
 * {@link ValueCallback#onReceiveValue(T) onReceiveValue()} will be called on the current
 * thread's {@link android.os.Looper} once the operation is complete.
 * The value provided to the callback indicates whether any cookies were removed.
 * You can pass {@code null} as the callback if you don't need to know when the operation
 * completes or whether any cookies were removed, and in this case it is safe to call the
 * method from a thread without a Looper.
 * @param callback a callback which is executed when the cookies have been removed
 */
public abstract void removeAllCookies(ValueCallback<Boolean> callback);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章