Jamendo开源在线音乐播放器源码分析(四)

时间:2022-11-01 10:23:06
四、网络操作,调用music API

HomeActivity上面那个gallery加载的是这周最流行的专辑,是用NewsTask异步加载的,下面来大体走一下请求网络api那一块的流程,在NewsTask的doInBackground()中:

JamendoGet2Api server = new JamendoGet2ApiImpl();
Album[] albums = null;
albums = server.getPopularAlbumsWeek();
com.teleca.jamendo.api 包是调用相关music API的接口包。
JamendoGet2Api 是调用music api的接口,由于调用这些api不需要任何形式的授权,不像比如调用新浪微博的接口,需要通过oauth授权,所以只要JamendoGet2Api service = new JamendoGet2ApiImpl();然后调用相应的方法,直接通过REST方式直接调用相应的api,我们看接口中的每个方法都有解释,相应的api也写出来了,更详尽的可以参考: http://developer.jamendo.com/en/wiki/Musiclist2Api

JamendoGet2ApiImpl就是对JamendoGet2Api的实现,我们跟踪下取得这周最流行专辑的getPopularAlbumsWeek()方法,是用GET方法请求的,跟踪到Caller类中的doGet()方法,http操作是使用Apache HTTP Client包,这个里面用了个缓存,将这次的请求结果会缓存起来,以减小网络开销,这个后面再说。

具体的http操作不多说了,大家看看代码就行,get方法返回了json串,可以直接在浏览器中访问这个api:http://api.jamendo.com/get2/id+name+url+image+artist_name/album/jsonpretty/?n=5&order=ratingweek_desc ,就可以看到返回的json串,android提供了处理json字符串的方法,我们可以看到返回的json串是一个大的JSONArray,里面每一项都是一个JSONObject,即对应的专辑的信息,getPopularAlbumsWeek()中把json串转化成了相应的对象的数组,这儿是Album[],即将每个JSONObject里的信息set到Album实体类中,主要是AlbumFunctions和AlbumBuilder两个类。

返回的Album[]给gallery的adapter使用,直接通过setList()方法放进去。网络操作这块大同小异,调用其他api步骤相似。

上面是一个具体的流程,异步请求一个api,网络操作返回json串,处理json转成对象,最后展示出来,这种网络封装大家也可以用在自己的代码中。jamendo层次结构很清晰,封装的也很好。

顺便说下Caller中用到的那个缓存。下面就是取得缓存和存入缓存的代码:

	/**
* Cache for most recent request
*/
private static RequestCache requestCache = null;

String data = null;
if(requestCache != null){
data = requestCache.get(url);
if(data != null){
Log.d(JamendoApplication.TAG, "Caller.doGet [cached] "+url);
return data;
}
}

if(httpEntity != null){
InputStream inputStream = httpEntity.getContent();
data = convertStreamToString(inputStream);
// cache the result
if(requestCache != null){
requestCache.put(url, data);
}

}
那程序是在哪new出这个RequestCache的对象的呢,我们发现Caller类里有一个静态的setRequestCache()的方法,说明哪儿调用了这个方法,而且是在这之前调用的,就想到了JamendoApplication这个全局的application,这个类在第一个activity执行之前先执行,有其自己的生命周期,在其onCreate()方法找到了setRequestCache()方法:

mRequestCache = new RequestCache();
Caller.setRequestCache(mRequestCache);
下面就看下RequestCache这个缓存类。

private LinkedList history;
private Hashtable<String, String> cache;
最多能缓存最新的10条数据,history一个队列用来存放请求的url,如果超过10个了,就将队首的poll出去。cache是一个hashtable用来存放对应url的返回的结果json,history主要是用来协助cache的remove操作的,如果你要查询的url已经在cache中了,则从cache中取出来,省去再次请求网络的开销。

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);
}