- 浏览: 61529 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
u014549257:
...
Apache Mina: StreamIoHandler传输文件处理 -
至尊包:
想问一下,这个官网的列子如果要兼容3.0以下的版本要怎么处理? ...
Swipe Views (水平分页)
仍旧沿用ExecutorService的例子, 修改了AsyncImageLoader调用线程管理池的方法。
AsyncImageLoader的思路:
1. 自定义RejectedExecutionHandler, 当线程任务被拒绝时,使其等待线程管理池空余后继续被调用。
2. 自定义线程管理池ThreadPoolExecutor替代ExecutorService
3. 线程的主要任务DownloadThreadTask,加载图片
4. 所有任务完成后,关闭自定义的ThreadPoolExecutor
源码:
自定义的RejectedExecutionHandler
自定义的ThreadPoolExecutor
线程任务DownloadThreadTask
AsyncImageLoader
下载的Activity对AsyncImageLoader的调用
---------------------------------------------------------------
以下使用 Callable 替代Runnable来进行图片的加载。 思路如上述所,只是修改一些源码。
1. 加载图片的 Callable
2. AsyncCallableLoader 替代 AsyncImageLoader
3. Activity调用AsnycCallableLoader
AsyncImageLoader的思路:
1. 自定义RejectedExecutionHandler, 当线程任务被拒绝时,使其等待线程管理池空余后继续被调用。
2. 自定义线程管理池ThreadPoolExecutor替代ExecutorService
3. 线程的主要任务DownloadThreadTask,加载图片
4. 所有任务完成后,关闭自定义的ThreadPoolExecutor
源码:
自定义的RejectedExecutionHandler
public class RejectedExcutionHandlerImpl implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { Log.i("test", ((DownloadThreadTask)r).getTask() + " is rejected"); // 如果出现线程任务被拒绝,则等待一段时间后,再次创建并提交到线程池中 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } executor.execute(r); Log.i("test",((DownloadThreadTask)r).getTask() + "再次创建并提交"); } }
自定义的ThreadPoolExecutor
public class CustomThreadPoolExecutor extends ThreadPoolExecutor { public CustomThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler){ super(corePoolSize,maximumPoolSize, keepAliveTime, unit, workQueue, handler); } // beforeExecute, afterExecute方法一般用于日志中,记录任务被调用前和完成后的状态 @Override protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); Log.i("test","perform before execute logic" + ((DownloadThreadTask)r).getTask()); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (t != null) { Log.i("test","Perform exception handler logic" + ((DownloadThreadTask)r).getTask()); } Log.i("test","Perform afterExecute() logic" + ((DownloadThreadTask)r).getTask()); } }
线程任务DownloadThreadTask
public class DownloadThreadTask implements Runnable { public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String,SoftReference<Drawable>>(); private String task; // 任务名称 private String url; // 加载URL private Handler handler; private ImageCallback callback; public DownloadThreadTask(String task, String url, Handler handler, ImageCallback callback){ this.task = task; this.url = url; this.handler = handler; this.callback = callback; } public String getTask() { return task; } public void setTask(String task) { this.task = task; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public Handler getHandler() { return handler; } public void setHandler(Handler handler) { this.handler = handler; } @Override public void run() { try { try{ Thread.sleep(10); }catch(InterruptedException e){ e.printStackTrace(); } final Drawable drawable = loadImageFromUrl(url); imageCache.put(url, new SoftReference<Drawable>(drawable)); handler.post(new Runnable() { public void run() { callback.imageLoader(drawable); } }); Log.i("test", "加载图片任务完成" + this.task); } catch (Exception e) { throw new RuntimeException(e); } } protected Drawable loadImageFromUrl(String imageUrl){ try { return Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png"); } catch (Exception e) { throw new RuntimeException(e); } } }
AsyncImageLoader
public class AsyncImageLoader { public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String,SoftReference<Drawable>>(); private BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(2); private RejectedExecutionHandler myReject = new RejectedExcutionHandlerImpl(); CustomThreadPoolExecutor executor = new CustomThreadPoolExecutor(1,2,5,TimeUnit.MILLISECONDS, blockingQueue, myReject); private final Handler handler = new Handler(); public Drawable loadDrawable(final String task, final String imageUrl, final ImageCallback callback){ if(imageCache.containsKey(imageUrl)){ SoftReference<Drawable> softReference = imageCache.get(imageUrl); if(softReference.get()!=null){ return softReference.get(); } } Log.i("test","创建任务并提交到线程池中:" + task); executor.execute(new DownloadThreadTask(task, imageUrl, handler, callback)); try { Thread.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return null; } public void shutdownAndAwaitTermination() { executor.shutdown(); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { executor.shutdownNow(); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled Log.i("test", "i am shutting down..."); if (!executor.awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } }catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted Log.e("test","something interrupted happend, and i am shutting down...."); executor.shutdownNow(); // Preserve interrupt status //Thread.currentThread().interrupt(); } } }
下载的Activity对AsyncImageLoader的调用
public class BatchDownloadActivity extends Activity { private static final String fileRealName = "我的图片1.gif"; private String url; private int id; private List<String> urls = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.batch_download); String fileName = fileRealName; String url = ""; try { url = ToolsUtil.getIpAddress() + URLEncoder.encode(fileRealName,"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Log.i("test","url=" + url); loadImage("task@1", url, R.id.imageView1); loadImage("task@2", url, R.id.imageView2); loadImage("task@3", url, R.id.imageView3); loadImage("task@4", url,R.id.imageView4); loadImage("task$5", url,R.id.imageView5); loader.shutdownAndAwaitTermination(); } private AsyncImageLoader loader = new AsyncImageLoader(); private void loadImage(final String task, final String url, final int id) { Drawable cacheImage = loader.loadDrawable(task, url,new ImageCallback() { @Override public void imageLoader(Drawable imageDrawable) { ((ImageView) findViewById(id)).setImageDrawable(imageDrawable); Log.i(task, "loading new pic:" +url); } }); if (cacheImage != null) { ((ImageView) findViewById(id)).setImageDrawable(cacheImage); Log.i("test", "loading existing pic"); } } }
---------------------------------------------------------------
以下使用 Callable 替代Runnable来进行图片的加载。 思路如上述所,只是修改一些源码。
1. 加载图片的 Callable
public class DownloadCallableTask implements Callable<Drawable> { public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String,SoftReference<Drawable>>(); private String task; private String url; public DownloadCallableTask(String task, String url){ this.task = task; this.url = url; } public String getTask(){ return this.task; } @Override public Drawable call() throws Exception { try{ Thread.sleep(10); }catch(InterruptedException e){ e.printStackTrace(); } if(imageCache.containsKey(url)){ SoftReference<Drawable> softReference = imageCache.get(url); if(softReference.get()!=null){ return softReference.get(); } } final Drawable drawable = loadImageFromUrl(url); imageCache.put(url, new SoftReference<Drawable>(drawable)); Log.i("test", "加载图片任务完成" + this.task); return drawable; } protected Drawable loadImageFromUrl(String imageUrl){ try { return Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png"); } catch (Exception e) { throw new RuntimeException(e); } } }
2. AsyncCallableLoader 替代 AsyncImageLoader
public class AsyncCallableLoader { private BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(2); ThreadPoolExecutor executor = new ThreadPoolExecutor(1,2,5,TimeUnit.MILLISECONDS, blockingQueue); private final Handler handler = new Handler(); public Drawable loadDrawable(final String task, final String imageUrl) throws InterruptedException, ExecutionException{ Log.i("test","创建任务并提交到线程池中:" + task); final Future<Drawable> future = executor.submit(new DownloadCallableTask(task,imageUrl)); try { Thread.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return future.get(); } public void shutdownAndAwaitTermination() { executor.shutdown(); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { executor.shutdownNow(); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled Log.i("test", "i am shutting down..."); if (!executor.awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } }catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted Log.e("test","something interrupted happend, and i am shutting down...."); executor.shutdownNow(); // Preserve interrupt status //Thread.currentThread().interrupt(); } } }
3. Activity调用AsnycCallableLoader
private AsyncCallableLoader loader = new AsyncCallableLoader(); private void loadImage(final String task, final String url, final int id) { Drawable cacheImage; try { cacheImage = loader.loadDrawable(task, url); if (cacheImage != null) { ((ImageView) findViewById(id)).setImageDrawable(cacheImage); Log.i("test", "loading pic"); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
发表评论
-
android RSS reader
2013-09-26 15:04 12751. AndroidManifest.xml中的activit ... -
关于ExecutorService的使用
2013-09-11 10:18 657ExecutorService: 线程池, 顾名思义是一个调度 ... -
使用后台服务下载文件的例子
2013-09-02 11:55 2146最近做了一个DEMO, 是通过httpURLConnectio ... -
Widget的开发: 一个最简单的例子
2013-06-14 10:29 1742首先,我们来说说基本概念。通常来说, 一个widget具备以下 ... -
Nofitication的使用
2013-05-22 15:16 999Notification的例子,请参考附件。 1. 创建N ... -
Contextual Action Mode
2013-05-13 16:05 2047我在网上查了N多文章, 结果发现,在ANDROID自带 ... -
GridView显示ICON和TEXT
2013-05-08 12:00 9931. 设置GridView的布局 <?xml ver ... -
Swipe Views (水平分页)
2013-05-07 13:36 15721. 创建activity public class Co ... -
ExpandableListFragment及其使用
2013-04-17 16:33 0xxxxxxxxxxxxxxx xxxxxxxxxxxx xx ... -
动态ActionBar
2013-04-17 16:32 1562首先介绍一下该应用的主要操作界面 1. ProvinceLay ... -
在DialogFragment中使用ExpandableList
2013-04-15 16:39 1492我本来想在ListFragment中使用Expanda ... -
Fragment开发实例
2013-03-15 12:15 1809SVN源码下载地址: https://svn.codespot ...
相关推荐
· 使用自定义ThreadPoolExecutor · 使用Executors.newCachedThreadPool() · 使用Executors.newFixedThreadPool(int) · 使用Executors.newSingleThreadExecutor() 其中使用2,3,4来创建线程池时...
轻量级动态线程池,内置监控告警功能,基于主流配置中心(已支持Nacos、Apollo、ZK,可通过SPI自定义实现)。对线程池 ThreadPoolExecutor 做一些扩展增强,主要实现以下目标:实现对运行中线程池参数的动态修改,...
真正的Addison-Wesley 出品的Java Concurrency in Practice 中文版 目录回到顶部↑ ...第14章 构建自定义的同步工具 第15章 原子变量与非阻塞同步机制 第16章 java存储模型 附录a 同步annotation 参考文献 索引
中文完整版的Java并发编程实践PDF电子书 作者:Brian Gogetz Tim Peierls Joshua Bloch Joseph Bowbeer David Holmes Doug Lea ...第14章 构建自定义的同步工具 第15章 原子变量与非阻塞同步机制 第16章 java存储模型
中文完整版的Java并发编程实践PDF电子书 作者:Brian Gogetz Tim Peierls Joshua Bloch Joseph Bowbeer David Holmes Doug Lea ...第14章 构建自定义的同步工具 第15章 原子变量与非阻塞同步机制 第16章 java存储模型
前言对于多线程,大家应该很熟悉。...开发者可根据不同需求 配置核心参数,从而实现自定义线程池 // 创建线程池对象如下 // 通过 构造方法 配置核心参数 Executor executor = new ThreadPoolExecutor
11.3.1 ThreadPoolExecutor / 407 11.3.2 线程池的分类 / 410 第12章 Bitmap的加载和Cache / 413 12.1 Bitmap的高效加载 / 414 12.2 Android中的缓存策略 / 417 12.2.1 LruCache / 418 12.2.2 ...
11.3.1 ThreadPoolExecutor 407 11.3.2 线程池的分类 410 第12章 Bitmap的加载和Cache 413 12.1 Bitmap的高效加载 414 12.2 Android中的缓存策略 417 12.2.1 LruCache 418 12.2.2 DiskLruCache 419 12.2.3 ...
zxing.java源码解析 ...ThreadPoolExecutor 多进程 Socket 网络编程 WebView 数据存储技术 多媒体 音频 视频 摄像头 位置与传感器 位置服务 其它传感器 硬件连接 蓝牙 NFC USB Wi-Fi P2P SIP 优秀开源框架
随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序...第14章 构建自定义的同步工具 第15章 原子变量与非阻塞同步机制 第16章 Java存储模型 附录A 同步Annotation 参考文献 索引
线程池中有6个核心参数,具体如下上述6个参数的配置决定了线程池的功能,具体设置时机=创建线程池类对象时传入ThreadPoolExecutor类=线程池的真正实现类开发者可根据不同需求配置核心参数,从而实现自定义线程池注:...
本书内容非常全面,涵盖了《Java编程思想》、《Java学习笔记》等书籍所有知识要点,并结合作者自己...线程池-ThreadPoolExecutor .....反射 ..........概述 ..........Class类 ..........类的加载 ..........操作对象
配置ThreadPoolExecutor(自定义的线程池) 此处需要注意系统默认提供的线程池是如何配置的 扩展ThreadPoolExector GUI应用程序探讨 活跃度(Liveness)、性能、测试 避免活跃性危险 死锁 锁...
如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的...
├─第一阶段 │ 源码+ppt.rar │ 高并发编程第一阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第一阶段02讲、简单介绍什么是线程.wmv ... 高并发编程第三阶段40讲 ThreadPoolExecutor关闭(很重要)精讲...
├─第一阶段 │ 源码+ppt.rar │ 高并发编程第一阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第一阶段02讲、简单介绍什么是线程.wmv ... 高并发编程第三阶段40讲 ThreadPoolExecutor关闭(很重要)精讲...