Androidラーニングシリーズ--Appキャッシュ管理

7381 ワード

http://www.cnblogs.com/qianxudetianxia/archive/2012/02/20/2112128.html
大規模またはスモールアプリケーションにかかわらず、柔軟なキャッシュは、サーバのストレスを大幅に軽減するだけでなく、より迅速なユーザー体験のためにユーザーを便利にしたと言えます.Androidのapkは小型アプリケーションとして言え、その99%がリアルタイムで更新する必要はなく、カタツムリのようなモバイルネットワークの速度を非難し、サーバとのデータインタラクションが少ないことが少なく、ユーザー体験がより良いのも、webviewを捨ててjsonでデータを転送することがある理由の一つです. キャッシュを採用することで、データ相互作用の圧力をさらに大幅に緩和することができ、特に、キャッシュ管理の適用環境を簡単に列挙する:1.ネットワークサービスを提供するアプリケーション2.データ更新はリアルタイム更新を必要としないが、3-5分の遅延でもキャッシュメカニズムを採用することができる. 3.キャッシュの期限切れは許容できる(キャッシュによるメリットではなく、一部のデータが更新が遅れて製品のイメージに影響するなど)メリット:1.サーバーの圧力が大幅に減少する2.クライアントの応答速度が大幅に速くなる(ユーザー体験)3.クライアントのデータロードエラーが大幅に少なく、安定性が大幅に向上する(ユーザ体験)4.オフラインブラウズをある程度サポートできる(またはオフラインブラウズにテクニカルサポートが提供されている)
一、キャッシュ管理の方法ここのキャッシュ管理の原理は簡単である:時間の設定によってキャッシュを読み取るか再ダウンロードするかを判断する.中には細かい処理があり、後で詳しく述べる.この原理に基づいて、現在私が見た2種類の比較的よく見られるキャッシュ管理方法は:データベース法とファイル法である.
二、データベース法キャッシュ管理この方法は、データファイルをダウンロードした後、url、経路、ダウンロード時間、期限切れ時間などのファイルに関する情報をデータベースに保存し、次のダウンロード時にurlに基づいてデータベースからクエリーし、現在の時間が期限切れでない場合は、パスに基づいてローカルファイルを読み取り、キャッシュの効果を実現する.この方法はファイルの属性を柔軟に保存することができ、さらに大きな拡張性を提供し、他の機能に一定のサポートを提供することができる.操作からデータベースを作成する必要があり、データベースを照会するたびに、期限切れになってもデータベースを更新する必要があり、保存を整理する際にデータベースデータを削除する必要があり、少し面倒で、データベースの操作が適切ではなく、容易である.一連の性能、ANRの問題が発生して、実現する時慎重にしなければならなくて、具体的に行うならば、しかしただ1つのツールクラスあるいは方法の事を増加します.もう1つの問題、キャッシュするデータベースは/data/data//databases/ディレクトリの下で保存して、メモリの空間を占有して、もしキャッシュが累計するならば、メモリを浪費しやすくて、直ちにキャッシュを整理する必要があります.もちろんこの方法は現在、いくつかの応用の実用的な面では、私は何の問題も発見していません.本文は第2の方法、第1の方法の実現を強調して、これでかすめました. 
三、ファイル法キャッシュ管理この方法は、File.lastModified()を使用する方法ファイルの最終修正時間を取得し、現在の時間と期限が切れたかどうかを判断してキャッシュ効果を実現する.実現上はこの属性しか使用できず、他の機能に技術サポートを提供する可能性はない.操作上は簡単で、時間を比較すればよい.自身の処理も他の問題をもたらしにくく、コストが安い.
四、ファイル法キャッシュ管理の二点説明1.異なる種類のファイルのキャッシュ時間が異なる.大まかに言えば、不変ファイルのキャッシュ時間は永久であり、変化ファイルのキャッシュ時間は最大で不変時間に耐える.白点を言えば、画像ファイルの内容はクリーンアップまで不変であり、私たちは永遠にキャッシュを読み取ることができる.ファイルの内容は更新可能であり、必要である許容可能なキャッシュ時間を設定します.2.環境によってキャッシュ時間の基準が異なります.ネットワーク環境がない場合、キャッシュファイルを読み取るしかありません.キャッシュが早く期限切れになっても.WiFiネットワーク環境では、キャッシュ時間を短く設定できます.1つは、ネットワーク速度が速く、トラフィックがお金を必要としません.モバイルデータトラフィック環境では、キャッシュ時間を長く設定し、ストリームを節約できます.量とは、お金を節約することであり、ユーザー体験もよりよいということです.例えば、最近本人が行っているアプリケーションのwifi環境でのキャッシュ時間を5分、モバイルデータトラフィックでのキャッシュ時間を1時間としています.この時間は、自分の実際の状況に応じて、データの更新頻度、データの重要性などを設定します.
五、いつ開発者をリフレッシュするかはできるだけキャッシュを読み取ることを望んでいる一方で、ユーザーはリアルタイムでリフレッシュすることを望んでいるが、応答速度が速ければ速いほど、流量消費が少なければ少ないほど、矛盾している.実はいつリフレッシュするかは私にも分からない.ここで私は2つの提案を提供する:1.データの最長どのくらいの時間は変わらず、応用に大きな影響はない.例えば、あなたのデータ更新時間は1日であるキャッシュ時間は4~8時間が適切で、一日に更新を見ることができます.もしあなたが情報類のアプリケーションだと思ったら、さらに減らして、2~4時間、データが重要だと思ったり、人気があると思ったら、ユーザーはよく游んで、さらに減らして、1~2時間、順番に類推します.保険のために、理由もなくもう一度減らす必要があるかもしれません.2.ブラシを提供します.新しいボタンです.上で述べた保険のために必ずしも保険ではありません.最も保険的な方法は、関連インタフェースにリフレッシュボタンを提供し、キャッシュを提供し、ロードに失敗したためにもう一度やり直す機会を提供します.このリフレッシュボタンがあれば、私たちの心も本当に下ろします.
六、ファイルキャッシュ法の具体的な実現はプロファイルのキャッシュに対して、私は新しいクラスConfigCacheを作った.
import java.io.File; 
import java.io.IOException; 
  
import android.util.Log; 
  
import com.tianxia.app.floworld.AppApplication; 
import com.tianxia.app.floworld.utils.FileUtils; 
import com.tianxia.app.floworld.utils.NetworkUtils; 
  
public class ConfigCache { 
    private static final String TAG = ConfigCache.class.getName(); 
  
    public static final int CONFIG_CACHE_MOBILE_TIMEOUT  = 3600000;  //1 hour 
    public static final int CONFIG_CACHE_WIFI_TIMEOUT    = 300000;   //5 minute 
  
    public static String getUrlCache(String url) { 
        if (url == null) { 
            return null; 
        } 
  
        String result = null; 
        File file = new File(AppApplication.mSdcardDataDir + "/" + getCacheDecodeString(url)); 
        if (file.exists() && file.isFile()) { 
            long expiredTime = System.currentTimeMillis() - file.lastModified(); 
            Log.d(TAG, file.getAbsolutePath() + " expiredTime:" + expiredTime/60000 + "min"); 
            //1. in case the system time is incorrect (the time is turn back long ago) 
            //2. when the network is invalid, you can only read the cache 
            if (AppApplication.mNetWorkState != NetworkUtils.NETWORN_NONE && expiredTime < 0) { 
                return null; 
            } 
            if(AppApplication.mNetWorkState == NetworkUtils.NETWORN_WIFI 
                   && expiredTime > CONFIG_CACHE_WIFI_TIMEOUT) { 
                return null; 
            } else if (AppApplication.mNetWorkState == NetworkUtils.NETWORN_MOBILE 
                   && expiredTime > CONFIG_CACHE_MOBILE_TIMEOUT) { 
                return null; 
            } 
            try { 
                result = FileUtils.readTextFile(file); 
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
        } 
        return result; 
    } 
  
    public static void setUrlCache(String data, String url) { 
        File file = new File(AppApplication.mSdcardDataDir + "/" + getCacheDecodeString(url)); 
        try { 
            //         ,       
            FileUtils.writeTextFile(file, data); 
        } catch (IOException e) { 
            Log.d(TAG, "write " + file.getAbsolutePath() + " data failed!"); 
            e.printStackTrace(); 
        } 
    } 
  
    public static String getCacheDecodeString(String url) { 
        //1.        
        //2.                   (              ,          ,         ) 
        if (url != null) { 
            return url.replaceAll("[.:/,%?&=]", "+").replaceAll("[+]+", "+"); 
        } 
        return null; 
    } 
}

  
実装上、いくつかの詳細を全面的に考慮し、注釈は説明されており、説明は省略されています.次に、呼び出し方法は次のとおりです.
void getConfig(){ 
        //         
        String cacheConfigString = ConfigCache.getUrlCache(CONFIG_URL); 
        //           ,       
        if (cacheConfigString != null) { 
            showConfig(cacheConfigString); 
        } else { 
            //        ,         
            //          1.   ;2.     ;3.       
            AsyncHttpClient client = new AsyncHttpClient(); 
            client.get(CONFIG_URL, new AsyncHttpResponseHandler(){ 
  
                @Override
                public void onSuccess(String result){ 
                    //    ,               
                    ConfigCache.setUrlCache(result,  CONFIG_URL); 
                    //     UI  ,     
                    showConfig(result); 
                } 
  
                @Override
                public void onFailure(Throwable arg0) { 
                    //      ,         ,        
                } 
  
            }); 
        } 
    }

 
これにより、プロファイルは有効にキャッシュされ、タイムリーに更新され、オフラインブラウズをサポートします.
七、小結スマートフォンのキャッシュ管理応用は非常に普遍的で需要であり、ユーザー体験を高める有効な手段の一つである.もちろん、キャッシュ管理のいくつかの内容は詳しく言われていない.例えば、画像キャッシュ、キャッシュクリーンアップなど、これらの処理は比較的簡単である.