import java.util.ArrayList;
import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Future; * 示例-异步渲染页面的文字和图片信息 * @author lufangpublic abstract class PageRenderer { private final ExecutorService executor = createExecutorService(); * 渲染页面 * @param source * 页面源码 public void renderPage(CharSequence source) { final List<String> imagePaths = scanForImagePaths(source); Callable<List<ImageData>> task = new Callable<List<ImageData>>() { public List<ImageData> call() { List<ImageData> result = new ArrayList<ImageData>(); for (String path : imagePaths) result.add(downloadImage(path)); return result; Future<List<ImageData>> future = executor.submit(task); renderText(source); try { List<ImageData> imageData = future.get(); for (ImageData data : imageData) renderImage(data); } catch (InterruptedException e) { // 因为在得到这个异常的同时,线程的中断状态已经被清除了,需要保留线程的中断状态,则需要调用Thread.currentThread().interrupt() Thread.currentThread().interrupt(); // 取消任务 future.cancel(true); } catch (ExecutionException e) { launderThrowable(e.getCause()); } finally {http://www.huiyi8.com/moban/ afterRender(); * 简单的抛出异常, 子类可覆盖并提供自己的实现 * @param cause * 接收到的异常 * @return Throwable 经检查后的异 protected Throwable launderThrowable(Throwable cause) { return new Throwable(cause);* * 渲染结束动作, 默认无操作, 子类可覆盖并提供自己的实现 protected void afterRender() { // do nothing * 交由子类决定如何构造线程池 * * @return ExecutorService 线程池 */ protected abstract ExecutorService createExecutorService(); * 交由子类决定如何提取图片地址 * @param source * 页面源码 * @return 图片地址列表 protected abstract List<String> scanForImagePaths(CharSequence source); * 交由子类决定如何下载文字 * @param source * 页面源码 protected abstract void renderText(CharSequence source); * 交由子类决定如何渲染图片 * * @param data * 图片信息 protected abstract void renderImage(ImageData data); * 交由子类决定如何下载图片 * @param path * 路径 * @return ImageData 图片信息 */ protected abstract ImageData downloadImage(String path);* 图片基本信息
* @author lufang public static class ImageData { private long height; private long width; private String uri; public long getHeight() { return height; public void setHeight(long height) { this.height = height; public long getWidth() { return width; public void setWidth(long width) { public String getUri() { return uri; public void setUri(String uri) { this.uri = uri;