- 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 lufang
- *
- */
- public 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 {
- 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) {
- this.width = width;
- }
- public String getUri() {
- return uri;
- }
- public void setUri(String uri) {
- this.uri = uri;
- }
- }
- }
- //该片段来自于http://www.codesnippet.cn/detail/2608201410341.html
来源: http://www.codesnippet.cn/detail/2608201410341.html