読書ノートApp研究開発録--データキャッシュ設計

11481 ワード

読書ノートApp研究開発録–データキャッシュ設計


ラベル(スペース区切り):データキャッシュandroid最適化

データ・キャッシュ・ポリシー


2 Gと3 Gネットワークの状態では、MobileApiのアクセス速度が遅すぎて、悪いユーザー体験を招く可能性があります.ネットワーク側のデータ受信の制限は主に伝送速度の制限である.ポリシー
  • MobileApiの呼び出し回数を減らす
  • Appキャッシュ時間.キャッシュデータ
  • を使用する期間呼び出し
    Appキャッシュは、データの即時性が要求されないデータにのみ使用されます.もちろん、必要に応じてAppキャッシュ時間を調整することもできます
    同じMobileApiに対しても入力パラメータが異なり、キャッシュは異なるはずです
    最も簡単な時間パラメータは、異なる時間に取得された天気の場合、date=Aとdate=Bがそれぞれ2つのキャッシュデータに対応するはずです.一緒に保管できません.

    キャッシュの場所

  • SDカード
  • Appはデータキャッシュが大きく、メモリの中でGCに回収されやすい.

    ほぞんモード


    データキャッシュはネットワーク層でa)urlを完了すべきである.xmlではMobileApiインタフェースごとにキャッシュ時間Expiredを設定し、Postでは0に設定します.
    public class URLData {
        private String key;
        private long expires; //     
        private String netType;
        private String url;
        private String mockClass;
    }

    b)並べ替えアルゴリズムsortKeysを書き、URLの中のkeyを並べ替える
    void sortKeys() {
            for (int i = 1; i < parameter.size(); i++) {
                for (int j = i; j > 0; j--) {
                    RequestParameter p1 = parameter.get(j - 1);
                    RequestParameter p2 = parameter.get(j);
                    if (compare(p1.getName(), p2.getName())) {
                        //   p1 p2     ,      
                        String name = p1.getName();
                        String value = p1.getValue();
    
                        p1.setName(p2.getName());
                        p1.setValue(p2.getValue());
    
                        p2.setName(name);
                        p2.setValue(value);
                    }
                }
            }
        }
        //   true  str1 ,  false  str2 
        boolean compare(String str1, String str2) {
            String uppStr1 = str1.toUpperCase();
            String uppStr2 = str2.toUpperCase();
    
            boolean str1IsLonger = true;
            int minLen = 0;
    
            if (str1.length() < str2.length()) {
                minLen = str1.length();
                str1IsLonger = false;
            } else {
                minLen = str2.length();
                str1IsLonger = true;
            }
    
            for (int index = 0; index < minLen; index++) {
                char ch1 = uppStr1.charAt(index);
                char ch2 = uppStr2.charAt(index);
                if (ch1 != ch2) {
                    if (ch1 > ch2) {
                        return true; // str1 
                    } else {
                        return false; // str2 
                    }
                }
            }
    
            return str1IsLonger;
        }

    c)newUrlを新しいkeyとしてキャッシュデータがあるか、あるか、戻るかをチェックする
    if (urlData.getExpires() > 0) {
                        final String content = CacheManager.getInstance()
                                .getFileCache(newUrl);
                        if (content != null) {
                            handler.post(new Runnable() {
    
                                @Override
                                public void run() {
                                    requestCallback.onSuccess(content);
                                }
    
                            });
    
                            return;
                        }
                    }

    d)そうでなければMobileApiを呼び出し続け、ネットワーク側からデータを取得し、キャッシュに入れる
    {
                            //               
                            if (urlData.getNetType().equals(REQUEST_GET)
                                    && urlData.getExpires() > 0) {
                                CacheManager.getInstance().putFileCache(newUrl,
                                        responseInJson.getResult(),
                                        urlData.getExpires());
                            }
    
                            handler.post(new Runnable() {
    
                                @Override
                                public void run() {
                                    requestCallback.onSuccess(responseInJson
                                            .getResult());
                                }
    
                            });
    
                            //   Cookie
                            saveCookie();
                        }

    e)CacheManagerのputFileCache()がデータの一意性操作を完了している(MD 5)
    public void putFileCache(final String key, final String data,
                long expiredTime) {
            String md5Key = BaseUtils.getMd5(key); //   Url     MD5
    
            final CacheItem item = new CacheItem(md5Key, data, expiredTime);
            putIntoCache(item);
        }

    f)MD 5暗号化の実現
     public static String getMd5(final String s)
        {
            try
            {
                // Create MD5 Hash
                final MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
                digest.update(s.trim().getBytes());
                final byte messageDigest[] = digest.digest();
                return BaseUtils.toHexString(messageDigest);
            }
            catch (final NoSuchAlgorithmException e)
            {
                e.printStackTrace();
            }
            return s;
        }
    
        /**
         *           
         * 
         * @param b
         *            byte  
         * @return String byte        
         */
        public static String toHexString(final byte[] b)
        {// String to byte
            final StringBuilder sb = new StringBuilder(b.length * 2);
            for (final byte element : b)
            {
                sb.append(BaseUtils.HEX_DIGITS[(element & 0xf0) >>> 4]);
                sb.append(BaseUtils.HEX_DIGITS[element & 0x0f]);
            }
            return sb.toString();
        }

    g)最後に、ローカルにシーケンス化可能なObjectタイプをシーケンス化する
    public static final void saveObject(String path, Object saveObject) {
            FileOutputStream fos = null;
            ObjectOutputStream oos = null;
            File f = new File(path);
            try {
                fos = new FileOutputStream(f);
                oos = new ObjectOutputStream(fos);
                oos.writeObject(saveObject);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (oos != null) {
                        oos.close();
                    }
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    強制更新


    RemoteServiceでは、App側のキャッシュポリシーに従うか否かを判断するbooleanタイプのパラメータが露出する、もしそうであればurlから.xmlでデータを読むとき(UrlDataエンティティ)、expiredを強制的に0に設定します.
    public void invoke(final BaseActivity activity, 
                final String apiKey,
                final List params,
                final RequestCallback callBack
                final boolean forceUpdate) {
    
                if(forceUpdate) {
                urlData.setExpires(0);
                }
        }