您的位置:首页 > 移动开发 > Android开发

Android Jamendo开源在线音乐播放器源码分析七 数据缓存和图片缓存的分析

2011-10-26 10:24 501 查看
在醒目中对于进行数据缓存和图片缓存的对象是在public class JamendoApplication extends Application这个Application里面进行创建和获取的。

对于Application先看一下API中的解释


Class Overview

Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's <application> tag, which will cause that class to be instantiated for you when the process for your
application/package is created.

There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve
it can be given a
Context
which internally uses
Context.getApplicationContext()
when
first constructing the singleton.
public class JamendoApplication extends Application {
	/**
	 * Singleton pattern     
	 */
	private static JamendoApplication instance;

	/**
	 * Image cache, one for all activities and orientations
	 */    
	private ImageCache mImageCache;

	/**
	 * Web request cache, one for all activities and orientations
	 */
	private RequestCache mRequestCache;
	
	@Override
	public void onCreate() {
		super.onCreate();
		mImageCache = new ImageCache();
		mRequestCache = new RequestCache();

		Caller.setRequestCache(mRequestCache);
		instance = this;

		mDownloadManager = new DownloadManagerImpl(this);
	}

	/**
	 * Access to global image cache across Activity instances
	 * 
	 * @return
	 */
	public ImageCache getImageCache() {
		return mImageCache;
	}
	
}
对于数据的缓存是通过一个类RequestCache来处理的

public class RequestCache {
	
	// TODO cache lifeTime
	
	private static int CACHE_LIMIT = 10;
	
	@SuppressWarnings("unchecked")
	private LinkedList history;
	private Hashtable<String, String> cache;
	
	@SuppressWarnings("unchecked")
	public RequestCache(){
		history = new LinkedList();
		cache = new Hashtable<String, String>();
	}
	
	@SuppressWarnings("unchecked")
	public void put(String url, String data){
		history.add(url);
		// too much in the cache, we need to clear something
		if(history.size() > CACHE_LIMIT){
			String old_url = (String) history.poll();
			cache.remove(old_url);
		}
		cache.put(url, data);
	}
	
	public String get(String url){
		return cache.get(url);
	}
}
将已经下载的最近10个数据放到一个HashTable<String,String>里面,如果HashTable里面有那么直接取出来,如果没有则加入,如果HashTable里面的数据超过了10个那个就把最晚的那个删除。

在HomeActivity里面有一个NewsTask的AsyncTask用以加载最近一个星期内最受欢迎的专辑

@Override
		public Album[] doInBackground(Void... params) {
			JamendoGet2Api server = new JamendoGet2ApiImpl();
			Album[] albums = null;
			try {
				albums = server.getPopularAlbumsWeek();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (WSError e){
				publishProgress(e);
			}
			return albums;
		}
会调用JamendoGet2ApiImpl里面想用的方法

private String doGet(String query) throws WSError{
		return Caller.doGet(GET_API + query);
	}

	@Override
	public Album[] getPopularAlbumsWeek() throws JSONException, WSError {
		
		String jsonString = doGet("id+name+url+image+rating+artist_name/album/json/?n=20&order=ratingweek_desc");
		if (jsonString == null)
			return null;
		
		try {
			JSONArray jsonArrayAlbums = new JSONArray(jsonString); 
			return AlbumFunctions.getAlbums(jsonArrayAlbums);
		} catch (NullPointerException e) {
			e.printStackTrace();
			throw new JSONException(e.getLocalizedMessage());
		}
	}
这里面会调用Caller里面的doGet()方法

public static String doGet(String url) throws WSError{
		
		String data = null;
		if(requestCache != null){
			data = requestCache.get(url);
			if(data != null){
				Log.d(JamendoApplication.TAG, "Caller.doGet [cached] "+url);
				return data;
			}
		}
		
		URI encodedUri = null;
		HttpGet httpGet = null;
		
		try {
			encodedUri = new URI(url);
			httpGet = new HttpGet(encodedUri);
		} catch (URISyntaxException e1) {
			// at least try to remove spaces
			String encodedUrl = url.replace(' ', '+');
			httpGet = new HttpGet(encodedUrl);
			e1.printStackTrace();
		}
		
		// initialize HTTP GET request objects
		HttpClient httpClient = new DefaultHttpClient();
		HttpResponse httpResponse;
		
		try {
			// execute request
			try {
				httpResponse = httpClient.execute(httpGet);
			} catch (UnknownHostException e) {
				throw new WSError("Unable to access " + e.getLocalizedMessage());
			} catch (SocketException e){
				throw new WSError(e.getLocalizedMessage());
			}
			
			// request data
			HttpEntity httpEntity = httpResponse.getEntity();
			
			if(httpEntity != null){
				InputStream inputStream = httpEntity.getContent();
				data = convertStreamToString(inputStream);
				// cache the result
				if(requestCache != null){
					requestCache.put(url, data);
				}
			}
			
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Log.d(JamendoApplication.TAG, "Caller.doGet "+url);
		return data;
	}


String data = null;
		if(requestCache != null){
			data = requestCache.get(url);
			if(data != null){
				Log.d(JamendoApplication.TAG, "Caller.doGet [cached] "+url);
				return data;
			}
		}
可以看出如果存放缓存的requestCache不是null,而且根据要取的url作为key从HashTable里面取出的的数据不是null,那么久可以直接取出缓存的数据,否则就要从网络获取,从网络获取后将其加入到缓存中

if(requestCache != null){
					requestCache.put(url, data);
				}


对于图片的缓存是通过ImageCache来处理的

public class ImageCache extends WeakHashMap<String, Bitmap> {

	private static final long serialVersionUID = 1L;
	
	public boolean isCached(String url){
		return containsKey(url) && get(url) != null;
	}

}

在PlayerActivity里面显示图片的空间不是直接用的ImageView而是RemoteImageView这个继承了ImageView的空间来处理的,在设置图片的时候是mCoverImageView.setImageUrl(playlistEntry.getAlbum().getImage().replaceAll("1.100.jpg", mBetterRes));是将在服务器上的地址传过来的

public void setImageUrl(String url){
		
		if(mListView == null && mCurrentlyGrabbedUrl != null && mCurrentlyGrabbedUrl.equals(url)){
			// do nothing image is grabbed & loaded, we are golden
			return;
		}
		
		if(mUrl != null && mUrl.equals(url)){
			mFailure++;
			if(mFailure > MAX_FAILURES){
				Log.e(JamendoApplication.TAG, "Failed to download "+url+", falling back to default image");
				loadDefaultImage();
				return;
			}
		} else {
			mUrl = url;
			mFailure = 0;
		}

		ImageCache imageCache = JamendoApplication.getInstance().getImageCache();
		if(imageCache.isCached(url)){
			this.setImageBitmap(imageCache.get(url));
		}
		else {
			try{
				new DownloadTask().execute(url);
			} catch (RejectedExecutionException e) {
				// do nothing, just don't crash
			}
		}
	}
如果ImageCache里面有则直接从缓存里面取出,如果没有启动一个异步任务进行加载。如果在启动的异步任务里面加载完了图片则将他加入到缓存中

JamendoApplication.getInstance().getImageCache().put(mTaskUrl, bmp);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐