Back to project page BBC-News-Reader.
The source code is released under:
Copyright (c) 2011, 2012, Digital Lizard (Oscar Key, Thomas Boby) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the...
If you think the Android project BBC-News-Reader listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/******************************************************************************* * BBC News Reader//w w w. j a va2 s . c om * Released under the BSD License. See README or LICENSE. * Copyright (c) 2011, Digital Lizard (Oscar Key, Thomas Boby) * All rights reserved. ******************************************************************************/ package com.digitallizard.bbcnewsreader.resource.web; import java.net.URL; import java.util.Iterator; import java.util.concurrent.PriorityBlockingQueue; import com.digitallizard.bbcnewsreader.ReaderActivity; import com.digitallizard.bbcnewsreader.ResourceInterface; public class WebManager implements Runnable { /* constants */ public static final int ITEM_TYPE_HTML = 2; public static final int ITEM_TYPE_THUMB = 1; public static final int ITEM_TYPE_IMAGE = 0; public static final int ERROR_FAIL_THRESHOLD = 4; /* variables */ PriorityBlockingQueue<QueueItem> downloadQueue; ResourceInterface handler; private boolean keepDownloading; Thread downloadThread; private volatile boolean noError; private volatile int numErrors; public synchronized boolean isQueueEmpty() { return downloadQueue.isEmpty(); } synchronized boolean shouldKeepDownloading() { return keepDownloading; } synchronized void setKeepDownloading(boolean keepDownloading) { this.keepDownloading = keepDownloading; } private void downloadItem(QueueItem item) { switch (item.getType()) { case ITEM_TYPE_HTML: downloadHtml(item); break; case ITEM_TYPE_THUMB: downloadThumbnail(item); break; case ITEM_TYPE_IMAGE: downloadImage(item); break; } } private void downloadHtml(QueueItem item) { try { byte[] html = HtmlParser.getPage(item.getUrl()); // load the page // before we report this download, check if it was a specific request if (item.wasSpecificallyRequested()) { handler.itemDownloadComplete(true, item.getItemId(), item.getType(), html); } else { handler.itemDownloadComplete(false, item.getItemId(), item.getType(), html); } } catch (Exception e) { numErrors++; // increment the number of errors if (numErrors > ERROR_FAIL_THRESHOLD) { // report the error // FIXME need to work out if internet error or not handler.reportError(ReaderActivity.ERROR_TYPE_INTERNET, "There was an error retrieving articles.", e.toString()); stopDownload(); // give up loading } } } private void downloadThumbnail(QueueItem item) { try { URL url = new URL(item.getUrl()); byte[] thumb = ImageDownloader.getImage(url); // load the image handler.itemDownloadComplete(false, item.getItemId(), item.getType(), thumb); } catch (Exception e) { numErrors++; // increment the number of errors if (numErrors > ERROR_FAIL_THRESHOLD) { // report the error // FIXME need to work out if internet error or not handler.reportError(ReaderActivity.ERROR_TYPE_INTERNET, "There was an error retrieving thumbnails.", e.toString()); stopDownload(); // give up loading } } } private void downloadImage(QueueItem item) { try { URL url = new URL(item.getUrl()); byte[] image = ImageDownloader.getImage(url); // load the image handler.itemDownloadComplete(false, item.getItemId(), item.getType(), image); } catch (Exception e) { numErrors++; // increment the number of errors if (numErrors > ERROR_FAIL_THRESHOLD) { // report the error handler.reportError(ReaderActivity.ERROR_TYPE_INTERNET, "There was an error retrieving images.", e.toString()); e.printStackTrace(); } } } private void itemQueued() { // check if we need to start the download thread if (!shouldKeepDownloading()) { // start the download thread setKeepDownloading(true); noError = true; downloadThread = new Thread(this); downloadThread.start(); } } public void addToQueue(String url, int type, int itemId) { // just call the main function with the type as the priority addToQueue(url, type, itemId, type); } public void addToQueue(String url, int type, int itemId, int priority) { QueueItem queueItem = new QueueItem(url, type, itemId, priority); downloadQueue.add(queueItem); itemQueued(); } public void loadNow(String url, int type, int itemId) { // check if a load is in progress if (shouldKeepDownloading()) { // loop through the queue to find the item we want, then boost its priority boolean itemExists = false; // set to true if the item was actually in the queue // FIXME looping efficient? probably doesn't matter as only on user command Iterator<QueueItem> iterator = downloadQueue.iterator(); while (iterator.hasNext()) { // check the id of this item QueueItem item = iterator.next(); if (item.getItemId() == itemId) { // boost the priority of this item item.setPriority(QueueItem.PRIORITY_DOWNLOAD_NOW); itemExists = true; // we found the item } } // if the item wasn't found, create it and set its priority high if (!itemExists) { addToQueue(url, type, itemId, QueueItem.PRIORITY_DOWNLOAD_NOW); } } else { // clear the queue, just in case emptyQueue(); // add the item to the queue, this will automatically start the download addToQueue(url, type, itemId, QueueItem.PRIORITY_DOWNLOAD_NOW); } } public void emptyQueue() { // check if a download is in progress if (shouldKeepDownloading()) { stopDownload(); // first stop downloading } downloadQueue.clear(); // empty the queue } public void stopDownload() { // check if the download is going if (shouldKeepDownloading()) { // try and stop the download noError = false; setKeepDownloading(false); // this will stop it after the current file emptyQueue(); // empty the queue } else { // as a load isn't in progress we can report that we have finished handler.fullLoadComplete(false); } } public void run() { // check this hasn't been called in error if (!isQueueEmpty()) { // keep downloading if we should while (shouldKeepDownloading()) { // retrieve the head of the queue and load it downloadItem(downloadQueue.poll()); // check if the queue is empty now if (isQueueEmpty()) { setKeepDownloading(false); // stop the loop } } handler.fullLoadComplete(noError); // report that the load is complete } } public WebManager(ResourceInterface handler) { this.handler = handler; downloadQueue = new PriorityBlockingQueue<QueueItem>(); numErrors = 0; // no errors yet } }