- 浏览: 62762 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
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 12991. AndroidManifest.xml中的activit ... -
关于ExecutorService的使用
2013-09-11 10:18 680ExecutorService: 线程池, 顾名思义是一个调度 ... -
使用后台服务下载文件的例子
2013-09-02 11:55 2176最近做了一个DEMO, 是通过httpURLConnectio ... -
Widget的开发: 一个最简单的例子
2013-06-14 10:29 1769首先,我们来说说基本概念。通常来说, 一个widget具备以下 ... -
Nofitication的使用
2013-05-22 15:16 1033Notification的例子,请参考附件。 1. 创建N ... -
Contextual Action Mode
2013-05-13 16:05 2072我在网上查了N多文章, 结果发现,在ANDROID自带 ... -
GridView显示ICON和TEXT
2013-05-08 12:00 10171. 设置GridView的布局 <?xml ver ... -
Swipe Views (水平分页)
2013-05-07 13:36 16131. 创建activity public class Co ... -
ExpandableListFragment及其使用
2013-04-17 16:33 0xxxxxxxxxxxxxxx xxxxxxxxxxxx xx ... -
动态ActionBar
2013-04-17 16:32 1591首先介绍一下该应用的主要操作界面 1. ProvinceLay ... -
在DialogFragment中使用ExpandableList
2013-04-15 16:39 1522我本来想在ListFragment中使用Expanda ... -
Fragment开发实例
2013-03-15 12:15 1853SVN源码下载地址: https://svn.codespot ...
相关推荐
自定义ThreadPoolExecutor允许更灵活的配置,以满足特定需求。 Java中实现多线程主要有三种方式:实现Runnable接口、继承Thread类以及使用ExecutorService、Callable和Future。实现Runnable接口是最常见的,适合不...
Android提供了HandlerThread、AsyncTask、IntentService或自定义ThreadPoolExecutor等方式进行线程管理。 9. **数据持久化**:为了记录下载状态(如下载链接、已下载大小、是否完成等),开发者可能使用SQLite...
如果你有大量并发任务,考虑使用其他机制,如IntentService、HandlerThread或自定义ThreadPoolExecutor。 最后,`asyntask`和`thread`标签表明这个例子还可能涉及到线程管理。在Android中,主线程(UI线程)不能...
可以自定义ThreadPoolExecutor,设置核心线程数、最大线程数、队列大小等参数,以适应不同场景的需求。 2. **并发容器**: Java集合框架中的并发容器,如ConcurrentHashMap、CopyOnWriteArrayList等,提供了线程...
建议根据实际需求自定义ThreadPoolExecutor,以更好地控制线程池的行为。 ArrayList的subList方法返回的是原列表的一个视图,直接修改可能导致意料之外的结果。谨慎使用subList是为了避免并发修改异常或逻辑错误。 ...
- **8.4 扩展ThreadPoolExecutor**:探讨了如何自定义ThreadPoolExecutor以满足特定需求。 - **8.5 并行递归**:介绍了一种通过递归来实现并行计算的技术。 这些内容提供了对Java并发编程深入理解的基础,适合...
· 使用自定义ThreadPoolExecutor · 使用Executors.newCachedThreadPool() · 使用Executors.newFixedThreadPool(int) · 使用Executors.newSingleThreadExecutor() 其中使用2,3,4来创建线程池时...
除了通过构造函数自定义线程池外,Java还提供了一些预定义的线程池,它们通过 `Executors` 工具类创建,适用于不同的应用场景。 1. **newFixedThreadPool**:创建一个固定大小的线程池,线程池的大小由参数 `...
7. **常见线程池实现**:除了自定义ThreadPoolExecutor外,Java还提供了Executors工具类,提供了一些预定义的线程池类型,如`newFixedThreadPool`(固定大小线程池)、`newSingleThreadExecutor`(单线程线程池)和`...
在并发方面,`api-http-utils-master`中的源码可能包含对线程池的管理,如自定义ThreadPoolExecutor或使用Executors提供的固定大小线程池,以控制并发程度和避免资源过度消耗。此外,库可能还考虑了线程安全问题,...
IS, new LinkedBlockingQueue()); }固定大小线程池使用了...在实际应用中,应根据任务特性和系统资源,选择适合的线程池实现,避免使用Executors的默认配置,而是自定义ThreadPoolExecutor以满足特定需求。
在Java中,可以使用`java.util.concurrent.ThreadPoolExecutor`来创建自定义线程池。通过设置核心线程数、最大线程数、线程存活时间等参数,可以调整线程池的行为以适应不同需求。 4. **任务调度器(Task Scheduler...
ThreadPoolExecutor线程池提供了灵活的线程管理机制,可以根据需要选择合适的任务队列和拒绝策略,并且可以自定义线程工厂和线程工具类,从而满足不同应用场景的需求。 ThreadPoolExecutor的使用方法可以分为以下几...
对于更复杂的应用场景,建议使用成熟的线程池框架,如`ThreadPoolExecutor`,它可以提供更完善的特性和更好的性能。 通过本次实践,我们不仅了解了线程池的工作原理,还学到了如何根据需求灵活定制线程池的行为,这...
4. `beforeExecute()`和`afterExecute()`,在任务执行前后调用,可以用于自定义监控和异常处理。 理解这些核心组件的工作方式,有助于我们在实际开发中更有效地使用线程池,优化系统的并发性能,并避免资源浪费。在...
`ThreadPoolExecutor`是线程池的默认实现类,它允许我们自定义线程池的核心参数,如核心线程数、最大线程数、空闲线程存活时间、工作队列和拒绝策略等。`ScheduledThreadPoolExecutor`则用于实现周期性任务调度。 `...
本篇文章主要介绍了Java多线程学习笔记之自定义线程池,通过深入了解ThreadPoolExecutor这个核心类,我们可以自定义线程池,满足不同的线程池需求。 Java多线程学习笔记之自定义线程池的重要性在于,它可以根据不同...
这可能涉及到使用异步任务(AsyncTask)或线程池(ThreadPoolExecutor)来处理耗时操作,并在UI线程更新进度条。 5. **使用帮助**:提供的“本源码使用帮助.txt”可能包含运行示例代码的步骤、注意事项以及可能遇到...
这个类是Spring对Java内置的`java.util.concurrent.ThreadPoolExecutor`的封装,允许开发者在Spring应用上下文中声明式地定义线程池。在本篇文章中,我们将深入探讨`ThreadPoolTaskExecutor`的配置及其使用,并结合`...
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } } ``` 在上面的代码中,我们创建了一个名为"taskExecutor"的线程池。该线程池具有以下参数: * 核心...