Android Webview - पूरी तरह से कैश को साफ़ करें


111

मेरे पास मेरी गतिविधियों में एक WebView है, और जब यह एक वेबपेज लोड करता है, तो पृष्ठ फेसबुक से कुछ पृष्ठभूमि डेटा इकट्ठा करता है।

हालांकि मैं जो भी देख रहा हूं, वह है कि एप्लिकेशन को प्रदर्शित किया जाने वाला पृष्ठ हर बार वही होता है जब ऐप खोला और ताज़ा किया जाता है।

मैंने 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 कहीं कैशिंग होना चाहिए।

आईआरसी चैनल पर मुझे एक URL कनेक्शन से कैशिंग हटाने के लिए एक ठीक करने के लिए कहा गया था, लेकिन यह नहीं देख सकता कि इसे अभी तक किसी WebView पर कैसे लागू किया जाए।

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

यदि मैं अपने एप्लिकेशन को हटाता हूं और इसे फिर से स्थापित करता हूं, तो मैं वेबपेज को अद्यतित कर सकता हूं, अर्थात गैर-कैश्ड संस्करण। मुख्य समस्या वेबपेज में लिंक के लिए किए गए बदलाव हैं, इसलिए वेबपेज का अगला छोर पूरी तरह से अपरिवर्तित है।


1
mWebView.getSettings().setAppCacheEnabled(false);काम नहीं किया?
पॉल

जवाबों:


45

गौंट फेस द्वारा पोस्ट किए गए ऊपर संपादित कोड स्निपेट में एक त्रुटि है कि अगर कोई निर्देशिका हटाने में विफल रहती है क्योंकि इसकी एक फ़ाइल को हटाया नहीं जा सकता है, तो कोड एक अनंत लूप में पुन: प्रयास करता रहेगा। मैंने इसे वास्तव में पुनरावर्ती होने के लिए फिर से लिखा है, और एक 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

यदि पूरी निर्देशिका को हटाने की आवश्यकता है तो Runtime.getRuntime () निष्पादित नहीं किया जाएगा। ("rm -rf" + dirName + "\ n"); आसान हो सकता है
source.rar

@ source.rar हां, लेकिन तब आपके पास x दिनों से पुरानी फाइलों को रखने की कोई क्षमता नहीं है, जो आम तौर पर आप कैश फ़ोल्डर के लिए चाहते हैं।
मार्जन

205

मुझे कैश समाशोधन के लिए एक और भी सुंदर और सरल समाधान मिला

WebView obj;
obj.clearCache(true);

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

मैं कैश को साफ करने के तरीके का पता लगाने की कोशिश कर रहा हूं, लेकिन उपरोक्त सभी तरीकों से हम स्थानीय फ़ाइलों को हटा सकते हैं, लेकिन यह रैम को कभी भी साफ नहीं करता है।

एपीआई क्लियरचेच, वेबव्यू द्वारा उपयोग की जाने वाली रैम को मुक्त करता है और इसलिए यह बताता है कि वेबपेज फिर से लोड किया गया है।


11
यहां सबसे अच्छा जवाब।
user486134 3

सबसे अच्छा जवाब और मुझे आश्चर्य है कि इसकी स्वीकृति क्यों नहीं दी गई .. कुडोस अक्षत :)
कार्तिक

1
मेरे लिए कोई किस्मत नहीं। आश्चर्य है कि अगर कुछ बदल गया है? मैं google.com के साथ एक WebView लोड कर सकता हूं और WebView अभी भी सोचता है कि मैं लॉग इन हूं, क्लीयरचेच (सच) के बाद भी;
खोया

2
@lostintranslation इसके लिए आप शायद कुकीज़ को हटाना चाहते हैं। हालांकि मुझे यकीन है कि आपने अब तक इसे ढूंढ लिया है।
नाइनटॉएड

वस्तु को आवंटित करने की आवश्यकता है? WebView obj = नया WebView (यह); obj.clearCache (सही); वैसे भी, मेरे लिए बहुत अच्छा, उत्थान!
जियोर्जियो बारची

45

मुझे वह ठीक मिला जिसे आप ढूंढ रहे थे:

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

किसी कारण से एंड्रॉइड url का खराब कैश बनाता है जो कि आपके द्वारा आवश्यक नए डेटा के बजाय दुर्घटना से वापस आ जाता है। ज़रूर, आप बस डीबी से प्रविष्टियों को हटा सकते हैं, लेकिन मेरे मामले में मैं केवल एक URL का उपयोग करने की कोशिश कर रहा हूं ताकि पूरे DB को उड़ाना आसान हो।

और चिंता न करें, ये DB आपके ऐप से जुड़े हैं इसलिए आप पूरे फोन के कैश को क्लियर नहीं कर रहे हैं।


धन्यवाद, यह एक अविश्वसनीय रूप से साफ-सुथरी चाल है। यह अधिक व्यापक रूप से ज्ञात होने के योग्य है।
फिलिप शियरड

2
यह मधुकोश में एक बुरा अपवाद फेंकता है: 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): डेटाबेस को खोलने में विफल। इसे बंद करना। 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): android.database.sqlite.SQLiteDiskIOException: डिस्क I / O त्रुटि 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): android.database पर। sqlite.SQLiteDatabase.native_setLocale (मूल विधि)
राफेल

चीयर्स राफेल, मैं यह सोचना चाहूंगा क्योंकि मूल मुद्दा हनीकॉम्ब में हल किया गया है। क्या किसी को पता है कि क्या यह मामला है?
स्कॉट

बस 2 लाइनों को ऑन बैकप्रेस () या बैक बटन में रखें कोई भी इतिहास बैक स्टैक में नहीं रहता है धन्यवाद बहुत समय बचा है।
क्रेज़ीमाइंड

36

जब आप अपना APP बनाते हैं, तो सभी वेबव्यू कैश को साफ़ करने के लिए:

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

लॉलीपॉप और इसके बाद के संस्करण के लिए:

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

1
मेरी जान और दिन बचाओ।
उदय नायक

2
यदि आपकी गतिविधि में वेबव्यू की पहुंच नहीं है तो ठीक काम करता है। यह भी ध्यान दें कि इस एपीआई को हटा दिया गया है, इसलिए L + उपकरणों के बजाय "RemoveAllCookies (ValueCallback)" API का उपयोग करें।
अक्षत

मुझे ValueCallBack से क्या बदलना चाहिए?
क़ैसर ख़ान बंगश

@QaisarKhanBangash नया मान कॉलबैक <बूलियन> () {atOverride public void onReceiveValue (बूलियन मान) {}}
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");
    }
}

यह कोशिश की (थोड़ा बदल कोड) और अभी भी एक ही परिणाम मिला -> ऊपर समझाया
मैट गंट

3

एकमात्र समाधान जो मेरे लिए काम करता है

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

2

बस कोटलिन में नीचे दिए गए कोड का उपयोग करना मेरे लिए काम करता है

WebView(applicationContext).clearCache(true)

2

वेब से कुकी और कैश साफ़ करने के लिए,

    // 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_oneवेबव्यू में एक खोल देता हूं , तो वेबव्यू में एक और खोलने की कोशिश करता हूं url_two, यह तब तक पृष्ठभूमिurl_one में दिखाता है जब तक लोड नहीं किया जाता है।url_two

समाधान: तो मैं क्या किया हल करने के लिए लोड खाली स्ट्रिंग है ""के रूप में urlसिर्फ छिपने से पहले url_oneऔर लोड हो रहा है url_two

आउटपुट: जब भी मैं किसी नए यूआरएल को वेबव्यू में लोड करता हूं तो वह बैकग्राउंड में कोई अन्य वेब पेज नहीं दिखाता है।

कोड

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 वोटिंग के लिए धन्यवाद, और मैं वास्तव में प्रतिक्रिया की सराहना करता हूं, और आपके सवाल का मेरा जवाब है, कि मैं समान परिदृश्य में फंस गया हूं, लेकिन मैं थोड़ा अलग हूं, लेकिन उन दोनों का आउटपुट एक ही है, इसलिए मेरा जवाब लिखने से पहले मैंने एक उपयोगकर्ता का मामला भी लिखा है, यह उसी तरह के प्रभाव को प्राप्त करेगा जैसा कि प्रश्न में पूछा गया है, कुकीज़ को संभालने की आवश्यकता के बिना।
अभिषेक गर्ग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.