HomeActivity上面那个gallery加载的是这周最流行的专辑,是用NewsTask异步加载的,下面来大体走一下请求网络api那一块的流程,在NewsTask的doInBackground()中:
JamendoGet2Api server = new JamendoGet2ApiImpl(); Album[] albums = null; albums = server.getPopularAlbumsWeek();com.teleca.jamendo.api 包是调用相关music API的接口包。
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); }