アクティビティの1つにWebViewがあり、Webページを読み込むと、ページは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で生成されたWebページに異なるHTMLコードを取得しているため、WebViewはどこかにキャッシュする必要があることがわかります。
IRCチャンネルでは、URL接続からキャッシュを削除する修正が示されましたが、WebViewにキャッシュを適用する方法がまだわかりません。
http://www.androidsnippets.org/snippets/45/
アプリケーションを削除して再インストールすると、ウェブページを最新の状態、つまりキャッシュされていないバージョンに戻すことができます。主な問題は、Webページ内のリンクが変更されるため、Webページのフロントエンドが完全に変更されないことです。
Gaunt Faceが投稿した上記の編集済みコードスニペットには、ファイルの1つを削除できないためにディレクトリの削除に失敗すると、コードが無限ループで再試行を続けるというエラーが含まれています。本当に再帰的になるように書き直し、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));
}
うまくいけば、他の人に役立つ:)
キャッシュをクリアするさらにエレガントでシンプルなソリューションを見つけました
WebView obj;
obj.clearCache(true);
http://developer.Android.com/reference/Android/webkit/WebView.html#clearCache%28boolean%29
私はキャッシュをクリアする方法を見つけようとしてきましたが、上記の方法からできることはローカルファイルを削除することだけでしたが、RAMを消去することはありませんでした。
API clearCacheは、Webビューで使用されるRAMを解放するため、Webページを再度ロードする必要があります。
あなたが探していた修正を見つけました:
context.deleteDatabase("webview.db");
context.deleteDatabase("webviewCache.db");
何らかの理由でAndroidは、必要な新しいデータではなく、誤ってURLのキャッシュを作成します。もちろん、DBからエントリを削除することもできますが、私の場合は1つのURLにアクセスしようとしているだけなので、DB全体を吹き飛ばすのは簡単です。
心配しないでください。これらのDBはアプリに関連付けられているだけなので、電話全体のキャッシュをクリアすることはありません。
APPからサインアウトしている間にすべてのwebviewキャッシュをクリアするには:
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
Lollipop以上の場合:
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookies(ValueCallback);
これにより、WebViewキャッシュがある場所にあるアプリケーションキャッシュがクリアされます。
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");
}
}
ユースケース:アイテムのリストは、いずれかのアイテムをクリックするとリサイクラービューを非表示にし、アイテムビューでアイテムビューとともにWebビューを表示します。
問題: webviewでurl_one
を開くと、webviewで別のurl_two
を開こうとすると、url_one
が表示されるという同様の問題があります- バックグラウンドurl_two
がロードされるまで。
solution:だから私がやったことを解決するためには、""
を非表示にしてurl_one
をロードする直前に、空の文字列url_two
をurl
としてロードします。
output: webviewで新しいURLを読み込むたびに、バックグラウンドで他のWebページが表示されません。
コード
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();
}
}
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
私のウェブビューでGoogleアカウントをクリアできます
履歴をクリアするには、単に以下を実行します。
this.appView.clearHistory();
出典: http://developer.Android.com/reference/Android/webkit/WebView.html
入力フィールドをクリックしたときにオートポップとしてフォームデータが表示されないようにするには、必ず以下のメソッドを使用してください。
getSettings().setSaveFormData(false);