2012-10-05 8 views
14

मेरा एंड्रॉइड ऐप आरईएसटी एपीआई का उपयोग कर अपना डेटा प्राप्त करता है। मैं क्लाइंट साइड कैशिंग लागू करना चाहता हूं। क्या हमारे पास इसके लिए कोई अंतर्निहित कक्षाएं हैं?आरईएसटी एपीआई परिणामों के लिए एंड्रॉइड ऐप में कैशिंग को कैसे कार्यान्वित करें?

यदि नहीं, तो क्या यह कोई कोड है जिसका मैं पुन: उपयोग कर सकता हूं? मुझे कुछ समय पहले इस तरह के कोड में आने याद है। हालांकि मैं इसे नहीं ढूंढ सकता।

यदि कुछ और काम नहीं करता है, तो मैं अपना खुद का लिखूंगा। निम्नलिखित बुनियादी संरचना

public class MyCacheManager { 

static Map<String, Object> mycache; 

public static Object getData(String cacheid) { 
    return mycache.get(cacheid); 
} 

public static void putData(String cacheid, Object obj, int time) { 
    mycache.put(cacheid, obj); 
} 

} 

कैश किए गए ऑब्जेक्ट्स के लिए मैं समय कैसे सक्षम करूं? भी - serialize करने का सबसे अच्छा तरीका क्या है? ऐप बंद होने पर भी कैश बरकरार होना चाहिए और बाद में फिर से खोल दिया जाना चाहिए (यदि समय समाप्त नहीं हुआ है)।

धन्यवाद अजय

उत्तर

3

का सबसे अच्छा तरीका http अनुरोध करता है कि स्मृति (कमजोर संदर्भ) और फ़ाइल पर में प्रतिक्रियाओं कैश बनाने के लिए librarys प्रज्वलित मथायस कैपलर का उपयोग करने के लिए है। यह वास्तव में एक या दूसरे या दोनों को करने के लिए विन्यास योग्य है।

पुस्तकालय यहाँ स्थित है: https://github.com/mttkay/ignition यहाँ स्थित उदाहरण के साथ: https://github.com/mttkay/ignition/wiki/Sample-applications

व्यक्तिगत रूप से, मैं जब यह Droidfu

आशा बुलाया गया था से इस lib प्यार यह आप के रूप में ज्यादा मदद करता है के रूप में यह मेरे अजय किया!

9

अब भयानक पुस्तकालय जो REST API बुलाने की सभी समस्याओं के साथ सुधार के लिए मदद करता है गूगल आई/ओ 2013 को जारी किया गया वॉली:

Volley is a library, यह Android देव टीम से पुस्तकालय बुलाया वॉली है। जो एंड्रॉइड ऐप्स के लिए नेटवर्किंग को आसान बनाता है और सबसे महत्वपूर्ण, तेज़। यह प्रसंस्करण और नेटवर्क अनुरोधों का कैशिंग प्रबंधित करता है और यह डेवलपर्स को समान नेटवर्क कॉल/कैश कोड को बार-बार लिखने से मूल्यवान समय बचाता है। और कम कोड रखने का एक और लाभ कम संख्या में बग है और यह सभी डेवलपर्स चाहते हैं और उनका लक्ष्य है। वॉली के लिए

उदाहरण: technotalkative

+0

वाह! आप यहां वॉली का उपयोग करने के कुछ अच्छे नमूने भी पा सकते हैं: https://github.com/stormzhang/AndroidVolley – Sam003

0

पहले डिवाइस की जांच इंटरनेट या नहीं से जुड़ा हुआ है।

public class Reachability { 

private final ConnectivityManager mConnectivityManager; 


public Reachability(Context context) { 
    mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
} 

public boolean isConnected() { 
    NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo(); 
    return networkInfo != null && networkInfo.isConnectedOrConnecting(); 
}} 

यदि डिवाइस इंटरनेट से कनेक्ट है तो एपीआई से डेटा प्राप्त करें और इसे कैश से डेटा प्राप्त करें।

public class CacheManager { 

Cache<String, String> mCache; 
private DiskLruCache mDiskLruCache; 
private final Context mContext; 

public CacheManager(Context context) throws IOException { 
    mContext = context; 
    setUp(); 
    mCache = DiskCache.getInstanceUsingDoubleLocking(mDiskLruCache); 
} 

public void setUp() throws IOException { 
    File cacheInFiles = mContext.getFilesDir(); 
    int version = BuildConfig.VERSION_CODE; 

    int KB = 1024; 
    int MB = 1024 * KB; 
    int cacheSize = 400 * MB; 

    mDiskLruCache = DiskLruCache.open(cacheInFiles, version, 1, cacheSize); 
} 

public Cache<String, String> getCache() { 
    return mCache; 
} 

public static class DiskCache implements Cache<String, String> { 

    private static DiskLruCache mDiskLruCache; 
    private static DiskCache instance = null; 

    public static DiskCache getInstanceUsingDoubleLocking(DiskLruCache diskLruCache){ 
     mDiskLruCache = diskLruCache; 
     if(instance == null){ 
      synchronized (DiskCache.class) { 
       if(instance == null){ 
        instance = new DiskCache(); 
       } 
      } 
     } 
     return instance; 
    } 

    @Override 
    public synchronized void put(String key, String value) { 
     try { 
      if (mDiskLruCache != null) { 
       DiskLruCache.Editor edit = mDiskLruCache.edit(getMd5Hash(key)); 
       if (edit != null) { 
        edit.set(0, value); 
        edit.commit(); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public synchronized String get(String key) { 
     try { 
      if (mDiskLruCache != null) { 
       DiskLruCache.Snapshot snapshot = mDiskLruCache.get(getMd5Hash(key)); 

       if (snapshot == null) { 
        // if there is a cache miss simply return null; 
        return null; 
       } 

       return snapshot.getString(0); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     // in case of error in reading return null; 
     return null; 
    } 

    @Override 
    public String remove(String key) { 
     // TODO: implement 
     return null; 
    } 

    @Override 
    public void clear() { 
     // TODO: implement 
    } 
} 

public static String getMd5Hash(String input) { 
    try { 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     byte[] messageDigest = md.digest(input.getBytes()); 
     BigInteger number = new BigInteger(1, messageDigest); 
     String md5 = number.toString(16); 

     while (md5.length() < 32) 
      md5 = "0" + md5; 

     return md5; 
    } catch (NoSuchAlgorithmException e) { 
     Log.e("MD5", e.getLocalizedMessage()); 
     return null; 
    } 
}} 

नेटवर्क प्रतिक्रिया कैश करने के लिए CacheInterceptor कक्षा बनाएं और त्रुटियों

public class CacheInterceptor implements Interceptor{ 
private final CacheManager mCacheManager; 
private final Reachability mReachability; 

public CacheInterceptor(CacheManager cacheManager, Reachability reachability) { 
    mCacheManager = cacheManager; 
    mReachability = reachability; 
} 

@Override 
public Response intercept(Chain chain) throws IOException { 
    Request request = chain.request(); 
    String key = request.url().toString(); 

    Response response; 
    if (mReachability.isConnected()) { 
     try { 
      response = chain.proceed(request); 
      Response newResponse = response.newBuilder().build(); 

      if (response.isSuccessful()) { 
       if (response.code() == 204) { 
        return response; 
       } 
       // save to cache this success model. 
       mCacheManager.getCache().put(key, newResponse.body().string()); 

       // now we know that we definitely have a cache hit. 
       return getCachedResponse(key, request); 
      }else if (response.code() >= 500) { // accommodate all server errors 

       // check if there is a cache hit or miss. 
       if (isCacheHit(key)) { 
        // if data is in cache, the return the data from cache. 
        return getCachedResponse(key, request); 
       }else { 
        // if it's a miss, we can't do much but return the server state. 
        return response; 
       } 

      }else { // if there is any client side error 
       // forward the response as it is to the business layers to handle. 
       return response; 
      } 
     } catch (ConnectException | UnknownHostException e) { 
      // Internet connection exception. 
      e.printStackTrace(); 
     } 
    } 

    // if somehow there is an internet connection error 
    // check if the data is already cached. 
    if (isCacheHit(key)) { 
     return getCachedResponse(key, request); 
    }else { 
     // if the data is not in the cache we'll throw an internet connection error. 
     throw new UnknownHostException(); 
    } 
} 

private Response getCachedResponse(String url, Request request) { 
    String cachedData = mCacheManager.getCache().get(url); 

    return new Response.Builder().code(200) 
      .body(ResponseBody.create(MediaType.parse("application/json"), cachedData)) 
      .request(request) 
      .protocol(Protocol.HTTP_1_1) 
      .build(); 
} 

public boolean isCacheHit(String key) { 
    return mCacheManager.getCache().get(key) != null; 
}} 

संभाल अब OkHttpClient में इस इंटरसेप्टर जोड़ने जबकि रेट्रोफिट का उपयोग कर सेवा का निर्माण।

public final class ServiceManager { 
private static ServiceManager mServiceManager; 

public static ServiceManager get() { 
    if (mServiceManager == null) { 
     mServiceManager = new ServiceManager(); 
    } 
    return mServiceManager; 
} 

public <T> T createService(Class<T> clazz, CacheManager cacheManager, Reachability reachability) { 
    return createService(clazz, HttpUrl.parse(ServiceApiEndpoint.SERVICE_ENDPOINT), cacheManager, reachability); 
} 

private <T> T createService(Class<T> clazz, HttpUrl parse, CacheManager cacheManager, Reachability reachability) { 
    Retrofit retrofit = getRetrofit(parse, cacheManager, reachability); 
    return retrofit.create(clazz); 
} 

public <T> T createService(Class<T> clazz) { 
    return createService(clazz, HttpUrl.parse(ServiceApiEndpoint.SERVICE_ENDPOINT)); 
} 

private <T> T createService(Class<T> clazz, HttpUrl parse) { 
    Retrofit retrofit = getRetrofit(parse); 
    return retrofit.create(clazz); 
} 

private <T> T createService(Class<T> clazz, Retrofit retrofit) { 
    return retrofit.create(clazz); 
} 

private Retrofit getRetrofit(HttpUrl httpUrl, CacheManager cacheManager, Reachability reachability) { 
    return new Retrofit.Builder() 
      .baseUrl(httpUrl) 
      .client(createClient(cacheManager, reachability)) 
      .addConverterFactory(getConverterFactory()) 
      .build(); 
} 

private OkHttpClient createClient(CacheManager cacheManager, Reachability reachability) { 
    return new OkHttpClient.Builder().addInterceptor(new CacheInterceptor(cacheManager, reachability)).build(); 
} 

private Retrofit getRetrofit(HttpUrl parse) { 
    return new Retrofit.Builder() 
      .baseUrl(parse) 
      .client(createClient()) 
      .addConverterFactory(getConverterFactory()).build(); 
} 

private Retrofit getPlainRetrofit(HttpUrl httpUrl) { 
    return new Retrofit.Builder() 
      .baseUrl(httpUrl) 
      .client(new OkHttpClient.Builder().build()) 
      .addConverterFactory(getConverterFactory()) 
      .build(); 
} 

private Converter.Factory getConverterFactory() { 
    return GsonConverterFactory.create(); 
} 

private OkHttpClient createClient() { 
    return new OkHttpClient.Builder().build(); 
}} 

कैश इंटरफ़ेस

public interface Cache<K, V> { 

void put(K key, V value); 

V get(K key); 

V remove(K key); 

void clear();} 
संबंधित मुद्दे