欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于ExecutorService的使用

程序员文章站 2022-03-24 12:37:42
...
ExecutorService: 线程池, 顾名思义是一个调度线程运行的管理池。 我预制了一个场景: 在界面上,有5个图片需要进行异步加载, 我们使用了一个线程池管理类 AsyncImageLoader来控制加载图片的线程个数,如果加载的图片原本已经存在,则从系统中调出已有图片进行加载; 如果图片是首次加载,则通过连接加载图片。

1. 需要加载5个图片的界面:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
android:text="图片区域开始"
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>

<ImageView
android:id="@+id/imageView1"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_width="wrap_content">
</ImageView>

<ImageView
android:id="@+id/imageView2"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_width="wrap_content">
</ImageView>

<ImageView
android:id="@+id/imageView3"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_width="wrap_content">
</ImageView>

<ImageView
android:id="@+id/imageView4"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_width="wrap_content">
</ImageView>

<ImageView
android:id="@+id/imageView5"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_width="wrap_content">
</ImageView>

<TextView
android:text="图片区域结束"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>


2. AsyncImageLoader类

public class AsyncImageLoader {

public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String,SoftReference<Drawable>>();

// 线程池的数量设置:在次,设置同时运行3个线程。
private ExecutorService executorService = Executors.newFixedThreadPool(3);

private final Handler handler = new Handler();

public ExecutorService getExecutorService() {
return executorService;
}

public void setExecutorService(ExecutorService executorService) {
this.executorService = executorService;
}

public Drawable loadDrawable(final String imageUrl, final ImageCallback callback){
// 如果缓存中已经加载过该图片,则调用缓存中的图片加载
if(imageCache.containsKey(imageUrl)){
SoftReference<Drawable> softReference = imageCache.get(imageUrl);

if(softReference.get()!=null){
return softReference.get();
}
}

// 首次加载图片的方法,使用线程池调用加载图片的线程
executorService.submit(new Runnable(){

@Override
public void run() {

try {
// 加载图片
final Drawable drawable = loadImageFromUrl(imageUrl);
// 将图片的加载路径保存到缓存中
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
// 图片加载完成后, 在界面中显示被加载的图片
handler.post(new Runnable() {
public void run() {
callback.imageLoader(drawable);
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}

});


return null;
}

protected Drawable loadImageFromUrl(String imageUrl){
try {
return Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png");
} catch (Exception e) {
throw new RuntimeException(e);
}

}
public interface ImageCallback{
public void imageLoader(Drawable imageDrawable);
}

// 关闭线程池
public void shutdownAndAwaitTermination(ExecutorService pool) {
// 关闭线程池,新的任务就不再运行
pool.shutdown(); // Disable new tasks from being submitted

try {
// Wait a while for existing tasks to terminate
// 设置一个等待时间,使原来已经存在的任务完成其工作
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {

pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
Log.i("test", "i am shutting down...");
if (!pool.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....");
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
}


3. 对AsyncImageLoader的调用异步加载这5个图片

public class BatchDownloadActivity extends Activity {

//需要加载的图片名称
private static final String fileRealName = "我的图片1.gif";
private String url;
private int id;


@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();
}
// url: http://xx.xx.xx.xx:port/webapp/filename.gif

Log.i("test","url=" + url);

// 调用加载图片方法
loadImage(url, R.id.imageView1);
loadImage(url, R.id.imageView2);
loadImage(url, R.id.imageView3);
loadImage(url,R.id.imageView4);
loadImage(url,R.id.imageView5);

//加载完成后,关闭线程管理池
loader.shutdownAndAwaitTermination(loader.getExecutorService());

}

private AsyncImageLoader loader = new AsyncImageLoader();

private void loadImage(final String url, final int id) {

Drawable cacheImage = loader.loadDrawable(url,new AsyncImageLoader.ImageCallback() {
@Override
public void imageLoader(Drawable imageDrawable) {

((ImageView) findViewById(id)).setImageDrawable(imageDrawable);
Log.i("test", "loading new pic");
}
});

if (cacheImage != null) {
((ImageView) findViewById(id)).setImageDrawable(cacheImage);
Log.i("test", "loading existing pic");
}

}

}
相关标签: android