《Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式》由会员分享,可在线阅读,更多相关《Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式(16页珍藏版)》请在金锄头文库上搜索。
1、android 线程池的理解,晚上在家无事 预习了一下 android 异步加载的例子,也学习到了一个很重要的东东 那就是线程池+缓存 下面看他们的理解。size=1.8emHandler+Runnable 模式我们先看一个并不是异步线程加载的例子,使用 Handler+Runnable 模式。这里为何不是新开线程的原因请参看这篇文章:Android Runnable 运行在那个线程 这里的代码其实是在 UI 主线程中下载图片的,而不是新开线程。我们运行下面代码时,会发现他其实是阻塞了整个界面的显示,需要所有图片都加载完成后,才能显示界面。?代码片段,双击复制01020304050607080
2、910111213packageghj1976.AndroidTest;importjava.io.IOException;.URL;importandroid.app.Activity;importandroid.graphics.drawable.Drawable;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.SystemClock;importandroid.util.Log;importandroid.widget.ImageView;publicclassMainActivityextendsAct
3、ivity OverridepublicvoidonCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.main);loadImage(http:/ R.id.imageView1);loadImage(,R.id.imageView2);loadImage(http:/ R.id.imageView3);loadImage(http:/ handler =newHandler();privatevoidloadImage(finalString url,fin
4、alintid) handler.post(newRunnable() publicvoidrun() Drawable drawable =null;trydrawable = Drawable.createFromStream(newURL(url).openStream(),image.gif);catch(IOException e) Log.d(test, e.getMessage();if(drawable =null) Log.d(test,null drawable);elseLog.d(test,not null drawable);/ 为了测试缓存而模拟的网络延时Syste
5、mClock.sleep(2000);(ImageView) MainActivity.this.findViewById(id).setImageDrawable(drawable););3637383940414243444546474849505152Handler+Thread+Message 模式这种模式使用了线程,所以可以看到异步加载的效果。核心代码:?代码片packageghj1976.AndroidTest;importjava.io.IOException;段,双击复制.URL;importandroid.app.Activity;importandroid.graphics
6、.drawable.Drawable;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Message;importandroid.os.SystemClock;importandroid.util.Log;importandroid.widget.ImageView;publicclassMainActivityextendsActivity OverridepublicvoidonCreate(Bundle savedInstanceState) super.onCreate(savedInstanceSta
7、te);setContentView(R.layout.main);loadImage2(http:/ R.id.imageView1);loadImage2(http:/ R.id.imageView3);loadImage2(http:/ handler2 =newHandler() OverridepublicvoidhandleMessage(Message msg) (ImageView) MainActivity.this.findViewById(msg.arg1).setImageDrawable(Drawable) msg.obj);/ 采用 handler+Thread 模
8、式实现多线程异步加载privatevoidloadImage2(finalString url,finalintid) Thread thread =newThread() Overridepublicvoidrun() 02122232425262728293031323334353637383940414Drawable drawable =null;trydrawable = Drawable.createFromStream(newURL(url).openStream(),image.png);catch(IOException e) Log.d(test, e.getMessage
9、();/ 模拟网络延时SystemClock.sleep(2000);Message message = handler2.obtainMessage();message.arg1 = id;message.obj = drawable;handler2.sendMessage(message);thread.start();thread =null;2434445464748495051525354555657585960616263这时候我们可以看到实现了异步加载, 界面打开时,五个 ImageView 都是没有图的,然后在各自线程下载完后才把图自动更新上去。Handler+Executo
10、rService(线程池)+MessageQueue 模式能开线程的个数毕竟是有限的,我们总不能开很多线程,对于手机更是如此。这个例子是使用线程池。Android 拥有与 Java 相同的 ExecutorService 实现,我们就来用它。线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。线程池的信息可以参看这篇文章:Java&Android 的线程池ExecutorService 下面的演示例子是创建一
11、个可重用固定线程数的线程池。核心代码?代码片段,双击复制01020304050607080910111packageghj1976.AndroidTest;importjava.io.IOException;.URL;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importandroid.app.Activity;importandroid.graphics.drawable.Drawable;importandroid.os.Bundle;importandroid.os.Ha
12、ndler;importandroid.os.Message;importandroid.os.SystemClock;importandroid.util.Log;importandroid.widget.ImageView;publicclassMainActivityextendsActivity OverridepublicvoidonCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.main);loadImage3(http:/ R.id.imageView1);loadImage3(http:/ handler =newHandler();privateExecutorService executorService = Executors.newFixedThreadPool(5);/ 引入线程池来管理多线程privatevoidloadImage3(finalString url,finalintid) executorService.submit(newRunnable() publicvoidrun() tryfinalDrawable drawa