Caching of data can make a huge difference in the performance of any application.

You want to centralizethe access to this data in one place and cache it, since retrieving it over the network isslow and expensive. You want to do this from the background Service, so that it canretrieve the data even when the main application isn’t being used and so that it can beexposed to the main application via IPC with the background Service.

Your background Service can be started at device boot. Then it canretrieve data over the network. This can be done periodically, as needed. Finally, oncethe user launches your application, one of your app’s activities can bind to the Serviceand invoke one of its methods to return the data that the Service downloadedfrom the network.

the list of stocks that the user wants to track is managed locally, stored in a local SQLite database. To track the current price of the stock, we’ll download this data over the network.

Stock Service now with caching.

modify the service class PortfolioManagerService:

//supports remote communication.
public class PortfolioManagerService extends Service {
private static final String TAG = "PortfolioManagerService";
// This is a data access object used for persisting stock information.
private StocksDb db;
// Timestamp of last time stock data was downloaded from the Itnernet
private long timestamp = 0L;
// How old downloaded stock data can be and still be used
private static final int MAX_CACHE_AGE = 15*60*1000; // 15 minutes
// Types of Notifications
private static final int HIGH_PRICE_NOTIFICATION = 1;
private static final int LOW_PRICE_NOTIFICATION = 0;

@Override
public void onCreate(){
super.onCreate();
db=new StocksDb(this);
}


@Override
public int onStartCommand(Intent intent, int flags, int startId){
if (db == null){
db = new StocksDb(this);
}
try {
updateStockData();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Service.START_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
db.close();
}
/*
* a Service usually run in its own process.Interprocess communication (IPC) is necessary.
* The onBind method is where the IPC channel is established.
*/
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
if (db == null){
db = new StocksDb(this);
}
// implement the IStockService interface defined in AIDL
// Stub class extends Binder.return.
return new IStockService.Stub() {
public Stock addToPortfolio(Stock stock) throws RemoteException {
Log.d(TAG, "Adding stock="+stock);
Stock s = db.addStock(stock);
Log.d(TAG, "Stock added to db");
try {
updateStockData();
for (Stock x:db.getStocks()){
if (x.getSymbol().equalsIgnoreCase(stock.getSymbol())){
s = x;
}
}
Log.d(TAG, "Stock data updated");
} catch (IOException e) {
Log.e(TAG, "Exception updating stock data", e);
throw new RemoteException();
}
return s;
}


public List<Stock> getPortfolio() throws RemoteException {
Log.d(TAG, "Getting portfolio");
ArrayList<Stock> stocks = db.getStocks();
long currTime = System.currentTimeMillis();
if (currTime - timestamp <= MAX_CACHE_AGE){
Log.d(TAG, "Fresh cache, returning it");
return stocks;
}
// else cache is stale, refresh it
Stock[] currStocks = new Stock[stocks.size()];
stocks.toArray(currStocks);
try {
Log.d(TAG, "Stale cache, refreshing it");
ArrayList<Stock> newStocks = fetchStockData(currStocks);
Log.d(TAG, "Got new stock data, updating cache");
updateCachedStocks(newStocks);
return newStocks;
} catch (Exception e) {
Log.e(TAG, "Exception getting stock data",e);
throw new RemoteException();
}
}
};
}
//update our cache with the fresh data
public void updateStockData ()throws IOException{
ArrayList<Stock> stocks = db.getStocks();
Stock[] currStocks = new Stock[stocks.size()];
currStocks = stocks.toArray(currStocks);
stocks = fetchStockData(currStocks);
updateCachedStocks(stocks);
}
private void updateCachedStocks(ArrayList<Stock> stocks){
Log.d(TAG, "Got new stock data to update cache with");
timestamp = System.currentTimeMillis();
Stock[] currStocks = new Stock[stocks.size()];
currStocks = stocks.toArray(currStocks);
for (Stock stock : currStocks){
Log.d(TAG, "Updating cache with stock=" + stock.toString());
db.updateStockPrice(stock);
}
Log.d(TAG, "Cache updated, checking for alerts");
checkForAlerts(stocks);
}

//retrieve data from the network
private ArrayList<Stock> fetchStockData(Stock[] stocks) throws IOException{
Log.d(TAG, "Fetching stock data from Yahoo");
ArrayList<Stock> newStocks=new ArrayList<Stock>(stocks.length);
if(stocks.length>0){
StringBuilder sb=new StringBuilder();
for(Stock stock:stocks){
sb.append(stock.getSymbol());
sb.append('+');
}
sb.deleteCharAt(sb.length()-1);
String urlStr="http://finance.yahoo.com/d/quotes.csv?f=sb2n&s="+sb.toString();
HttpClient client=new DefaultHttpClient();
HttpGet request=new HttpGet(urlStr.toString());
HttpResponse response=client.execute(request);
BufferedReader reader=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line=reader.readLine();
int i=0;
Log.d(TAG, "Parsing stock data from Yahoo");
while(line!=null){
Log.d(TAG, "Parsing: " + line);
String[] values=line.split(",");
Stock stock=new Stock(stocks[i],stocks[i].getId());
stock.setCurrentPrice(Double.parseDouble(values[1]));
stock.setName(values[2]);
Log.d(TAG, "Parsed Stock: " + stock);
newStocks.add(stock);
line=reader.readLine();
i++;
}


}
return newStocks;
}

private void checkForAlerts(Iterable<Stock> stocks){

}
}

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. Java学习之面向对象三
  2. java微信小程序解密AES/CBC/PKCS7Padding
  3. 包含带标记的值的XML属性文件
  4. JAVA实现排序-冒泡排序-优化冒泡排序
  5. 不幸的是,在声明按钮时,模拟器中出现了错误
  6. spark seq.max 报错 Caused by: java.lan
  7. 排序算法之 Java简单快速排序算法
  8. Java正则表达式提取字符
  9. Map集合的使用
  10. Java错误:线程“main”中的异常java.lang.