Android Webview-캐시 완전 삭제


111

내 활동 중 하나에 WebView가 있고 웹 페이지를로드 할 때 페이지가 Facebook에서 배경 데이터를 수집합니다.

그래도 내가 보는 것은 응용 프로그램에 표시된 페이지가 앱을 열고 새로 고칠 때마다 동일하다는 것입니다.

캐시를 사용하지 않고 WebView의 캐시 및 기록을 지우도록 WebView를 설정하려고 시도했습니다.

또한 여기 제안을 따랐습니다. WebView의 캐시를 비우는 방법?

그러나이 중 어느 것도 작동하지 않습니다.이 문제는 내 응용 프로그램의 중요한 부분이기 때문에이 문제를 극복 할 수 있다는 생각이있는 사람은 없습니다.

    mWebView.setWebChromeClient(new WebChromeClient()
    {
           public void onProgressChanged(WebView view, int progress)
           {
               if(progress >= 100)
               {
                   mProgressBar.setVisibility(ProgressBar.INVISIBLE);
               }
               else
               {
                   mProgressBar.setVisibility(ProgressBar.VISIBLE);
               }
           }
    });
    mWebView.setWebViewClient(new SignInFBWebViewClient(mUIHandler));
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.clearHistory();
    mWebView.clearFormData();
    mWebView.clearCache(true);

    WebSettings webSettings = mWebView.getSettings();
    webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

    Time time = new Time();
    time.setToNow();

    mWebView.loadUrl(mSocialProxy.getSignInURL()+"?time="+time.format("%Y%m%d%H%M%S"));

그래서 첫 번째 제안을 구현했습니다 (코드를 재귀 적으로 변경했지만)

private void clearApplicationCache() {
    File dir = getCacheDir();

    if (dir != null && dir.isDirectory()) {
        try {
            ArrayList<File> stack = new ArrayList<File>();

            // Initialise the list
            File[] children = dir.listFiles();
            for (File child : children) {
                stack.add(child);
            }

            while (stack.size() > 0) {
                Log.v(TAG, LOG_START + "Clearing the stack - " + stack.size());
                File f = stack.get(stack.size() - 1);
                if (f.isDirectory() == true) {
                    boolean empty = f.delete();

                    if (empty == false) {
                        File[] files = f.listFiles();
                        if (files.length != 0) {
                            for (File tmp : files) {
                                stack.add(tmp);
                            }
                        }
                    } else {
                        stack.remove(stack.size() - 1);
                    }
                } else {
                    f.delete();
                    stack.remove(stack.size() - 1);
                }
            }
        } catch (Exception e) {
            Log.e(TAG, LOG_START + "Failed to clean the cache");
        }
    }
}

그러나 이것은 여전히 ​​페이지에 표시되는 내용을 변경하지 않았습니다. 내 데스크톱 브라우저에서 WebView에서 생성 된 웹 페이지와 다른 html 코드를 얻고 있으므로 WebView가 어딘가에 캐싱해야 함을 알고 있습니다.

IRC 채널에서 URL 연결에서 캐싱을 제거하는 수정 사항을 지적했지만 아직 WebView에 적용하는 방법을 볼 수 없습니다.

http://www.androidsnippets.org/snippets/45/

내 응용 프로그램을 삭제하고 다시 설치하면 웹 페이지를 캐시되지 않은 버전과 같은 최신 상태로 되돌릴 수 있습니다. 주요 문제는 웹 페이지의 링크가 변경되어 웹 페이지의 프런트 엔드가 완전히 변경되지 않는다는 것입니다.


1
mWebView.getSettings().setAppCacheEnabled(false);작동하지 않았습니까?
Paul

답변:


45

Gaunt Face가 게시 한 위의 편집 된 코드 스 니펫에는 파일 중 하나를 삭제할 수 없어 디렉토리가 삭제되지 않으면 코드가 무한 루프에서 계속 재 시도한다는 오류가 있습니다. 정말 재귀 적이되도록 다시 작성하고 numDays 매개 변수를 추가하여 정리할 파일의 수명을 제어 할 수 있습니다.

//helper method for clearCache() , recursive
//returns number of deleted files
static int clearCacheFolder(final File dir, final int numDays) {

    int deletedFiles = 0;
    if (dir!= null && dir.isDirectory()) {
        try {
            for (File child:dir.listFiles()) {

                //first delete subdirectories recursively
                if (child.isDirectory()) {
                    deletedFiles += clearCacheFolder(child, numDays);
                }

                //then delete the files and subdirectories in this dir
                //only empty directories can be deleted, so subdirs have been done first
                if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) {
                    if (child.delete()) {
                        deletedFiles++;
                    }
                }
            }
        }
        catch(Exception e) {
            Log.e(TAG, String.format("Failed to clean the cache, error %s", e.getMessage()));
        }
    }
    return deletedFiles;
}

/*
 * Delete the files older than numDays days from the application cache
 * 0 means all files.
 */
public static void clearCache(final Context context, final int numDays) {
    Log.i(TAG, String.format("Starting cache prune, deleting files older than %d days", numDays));
    int numDeletedFiles = clearCacheFolder(context.getCacheDir(), numDays);
    Log.i(TAG, String.format("Cache pruning completed, %d files deleted", numDeletedFiles));
}

다른 사람들에게 유용하기를 바랍니다. :)


감사합니다! 너희들은 내 하루 :) 저장
크리스

훌륭한 루틴으로 많은 고통을 덜어주었습니다.
미스터 에드

앱 내에서이 코드를 사용하여 휴대폰에 설치된 특정 앱의 캐시를 지울 수 있습니까?
Si8 2013 년

전체 디렉토리를 삭제해야하는 경우 Runtime.getRuntime (). exec ( "rm -rf"+ dirName + "\ n"); 더 쉬울까요?
source.rar

@ source.rar 예,하지만 일반적으로 캐시 폴더에 필요한 x 일 이전의 파일을 보관할 수 없습니다.
markjan 2014 년

205

캐시 지우기에 대한 훨씬 우아하고 간단한 솔루션을 찾았습니다.

WebView obj;
obj.clearCache(true);

http://developer.android.com/reference/android/webkit/WebView.html#clearCache%28boolean%29

캐시를 지우는 방법을 알아 내려고 노력했지만 위에서 언급 한 방법으로 할 수있는 일은 로컬 파일을 제거하는 것이지만 RAM을 청소하지는 않습니다.

API clearCache는 웹보기에서 사용하는 RAM을 비우므로 웹 페이지를 다시로드해야합니다.


11
여기에 가장 좋은 대답입니다.
user486134 2013

내가 왜 그되지 accepted..Kudos Akshat :) 궁금하고 가장 좋은 대답
KARTHIK

1
나에게는 운이 없다. 변경된 것이 있는지 궁금하십니까? google.com을 사용하여 WebView를로드 할 수 있으며 WebView는 clearCache (true) 후에도 여전히 로그인 한 것으로 인식합니다.
lostintranslation 2015 년

2
@lostintranslation이를 위해 아마도 쿠키를 삭제하고 싶을 것입니다. 나는 당신이 지금 쯤 그것을 발견했다고 확신하지만.
NineToeNerd

개체를 할당해야합니까? WebView obj = new WebView (this); obj.clearCache (true); 어쨌든, 나에게 매우 좋습니다.
Giorgio Barchiesi

45

찾고 있던 수정 사항을 찾았습니다.

context.deleteDatabase("webview.db");
context.deleteDatabase("webviewCache.db");

어떤 이유로 Android는 필요한 새 데이터 대신 실수로 계속 반환하는 URL의 잘못된 캐시를 만듭니다. 물론, DB에서 항목을 삭제할 수는 있지만 제 경우에는 하나의 URL에만 액세스하려고하므로 전체 DB를 날리는 것이 더 쉽습니다.

걱정하지 마세요. 이러한 DB는 앱과 연결되어 있으므로 전체 전화의 캐시를 지우지 않아도됩니다.


감사합니다. 이것은 믿을 수 없을 정도로 깔끔한 트릭입니다. 더 널리 알려질 가치가 있습니다.
Philip Sheard

2
이로 인해 벌집에서 불쾌한 예외가 발생합니다. 06-14 22 : 33 : 34.349 : ERROR / SQLiteDatabase (20382) : 데이터베이스를 열지 못했습니다. 닫습니다. 06-14 22 : 33 : 34.349 : ERROR / SQLiteDatabase (20382) : android.database.sqlite.SQLiteDiskIOException : disk I / O error 06-14 22 : 33 : 34.349 : ERROR / SQLiteDatabase (20382) : at android.database. sqlite.SQLiteDatabase.native_setLocale (기본 방법)
라파엘 산체스

라파엘 건배, 허니컴에서 원래 문제가 해결 되었기 때문이라고 생각합니다. 이것이 사실인지 아는 사람이 있습니까?
스콧

onBackpress () 또는 뒤로 버튼에 2 줄만 넣으면 많은 시간이 절약되어 백 스택에 기록이 남아 있지 않습니다.
CrazyMind

36

앱에서 로그 아웃하는 동안 모든 웹뷰 캐시를 지우려면 :

CookieSyncManager.createInstance(this);         
CookieManager cookieManager = CookieManager.getInstance();        
cookieManager.removeAllCookie();

Lollipop 이상 :

CookieSyncManager.createInstance(this);         
CookieManager cookieManager = CookieManager.getInstance();        
cookieManager.removeAllCookies(ValueCallback);

1
내 생명과 날을 구하십시오.
Uday Nayak

2
활동에서 webview에 액세스 할 수없는 경우 제대로 작동합니다. 또한이 API는 더 이상 사용되지 않으므로 L + 장치에서 대신 "removeAllCookies (ValueCallback)"API를 사용하십시오.
Akshat

ValueCallBack으로 무엇을 대체해야합니까?
Qaisar Khan Bangash

@QaisarKhanBangash new ValueCallback <Boolean> () {atOverride public void onReceiveValue (Boolean value) {}}
amalBit

3

웹뷰 캐시가있는 애플리케이션 캐시를 지워야합니다.

File dir = getActivity().getCacheDir();

if (dir != null && dir.isDirectory()) {
    try {
        File[] children = dir.listFiles();
        if (children.length > 0) {
            for (int i = 0; i < children.length; i++) {
                File[] temp = children[i].listFiles();
                for (int x = 0; x < temp.length; x++) {
                    temp[x].delete();
                }
            }
        }
    } catch (Exception e) {
        Log.e("Cache", "failed cache clean");
    }
}

이것을 시도 (약간 변경된 코드)하고 여전히 동일한 결과를 얻었습니다-> 위에서 설명
Matt Gaunt

3

나를 위해 일하는 유일한 솔루션

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
    CookieManager.getInstance().removeAllCookies(null);
    CookieManager.getInstance().flush();
} 

2

Kotlin에서 아래 코드를 사용하면 효과적입니다.

WebView(applicationContext).clearCache(true)

2

Webview에서 쿠키 및 캐시를 삭제하려면

    // Clear all the Application Cache, Web SQL Database and the HTML5 Web Storage
    WebStorage.getInstance().deleteAllData();

    // Clear all the cookies
    CookieManager.getInstance().removeAllCookies(null);
    CookieManager.getInstance().flush();

    webView.clearCache(true);
    webView.clearFormData();
    webView.clearHistory();
    webView.clearSslPreferences();


0

입력 필드를 클릭 할 때 양식 데이터가 자동 팝업으로 표시되지 않도록하려면 아래 방법을 사용하십시오.

getSettings().setSaveFormData(false);

0
CookieSyncManager.createInstance(this);         
CookieManager cookieManager = CookieManager.getInstance();        
cookieManager.removeAllCookie();

0
CookieSyncManager.createInstance(this);    
CookieManager cookieManager = CookieManager.getInstance(); 
cookieManager.removeAllCookie();

내 webview에서 Google 계정을 지울 수 있습니다.


2
CookieSyncManager가 더 이상 사용되지 않음
개발자

-1

유스 케이스 : 아이템 목록이 리사이클 러 뷰에 표시되고, 아이템을 클릭 할 때마다 리사이클 러 뷰를 숨기고 아이템 URL과 함께 웹 뷰를 보여줍니다.

문제 : 나는 일단 내가 url_onewebview에서 열면, webview에서 다른 것을 열려고 시도하면 url_two, 로드 될 때까지 백그라운드url_one 에서 보여 지는 비슷한 문제 가 있습니다.url_two

솔루션 : 그래서 내가 한 일을 해결하기 위해 숨기기 및로드 직전에 빈 문자열 ""을 로드 합니다.urlurl_oneurl_two

출력 : webview에서 새 URL을로드 할 때마다 백그라운드에 다른 웹 페이지가 표시되지 않습니다.

암호

public void showWebView(String url){
        webView.loadUrl(url);
        recyclerView.setVisibility(View.GONE);
        webView.setVisibility(View.VISIBLE);
    }

public void onListItemClick(String url){
   showWebView(url);
}

public void hideWebView(){
        // loading blank url so it overrides last open url
        webView.loadUrl("");
        webView.setVisibility(View.GONE);
        recyclerView.setVisibility(View.GONE);
   }


 @Override
public void onBackPressed() {
    if(webView.getVisibility() == View.VISIBLE){
        hideWebView();
    }else{
        super.onBackPressed();
    }
}

이것이 질문과 어떤 관련이 있습니까?
Zun

@Zun은 다운 투표에 감사 드리며 피드백을 주셔서 감사합니다. 귀하의 질문에 대한 제 대답은 비슷한 시나리오에 갇혀 있지만 약간 다르지만 둘 다 출력이 동일하므로 내 답변을 작성하기 전에 나는 또한 사용자 사례를 작성했는데, 쿠키를 처리 할 필요없이 질문에서 요청한 것과 유사한 효과를 얻을 것입니다.
Abhishek Garg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.