后天就是大年初一啦炭剪!提前祝大家2017年大吉大利!
步入正題
其實(shí)我們從網(wǎng)絡(luò)上拉取(加載)一張圖片很簡(jiǎn)單,隨隨便便幾行代碼搞定涯冠,那我們的圖片拉取池的意義在什么地方呢?首先我們用于圖片拉取的線程是可控的逼庞,也就是說(shuō)可以隨時(shí)取消蛇更。其次我們內(nèi)部封裝了一層線程池,保證了我們拉取的圖片是有序的赛糟。對(duì)于如何得到拉取之后的圖片派任,我采用的是接口回調(diào),每拉取一次都會(huì)返回給調(diào)用者裆针。
好罢绽,現(xiàn)在我們看代碼舔痪。
public class ThreadPool {
private static ExecutorService exec;
private static ThreadPool threadPool;
public static ThreadPool getInstance(){
if(threadPool != null){
return threadPool;
}
synchronized (ThreadPool.class) {
if(threadPool == null){
threadPool = new ThreadPool();
}
}
return threadPool;
}
private ThreadPool(){
exec = Executors.newFixedThreadPool(1);
}
public ThreadListener exec(Runnable runnable){
Future<?> future = exec.submit(runnable);
ThreadListener listener = new ThreadListener(future);
return listener;
}
public static class ThreadListener{
private Future<?> f;
public ThreadListener(Future<?> future){
this.f = future;
}
//試圖取消線程,返回true表示取消成功
public boolean cancle(){
return f.cancel(true);
}
//判斷是否完成
public boolean isDone(){
return f.isDone();
}
}
}
這里使用單例模式對(duì)線程池進(jìn)行了一層封裝豆混,注意這里我們并沒(méi)有使用execute()方法,而是采用submit方法并返回一個(gè)Future對(duì)象动知,這樣做的好處就是皿伺,我們可以控制線程,可以隨時(shí)取消并且判斷是否完成等等盒粮。
public interface Callback {
void getBitmap(Bitmap bitmap);
}
接口鸵鸥,用于返回bitmap。
public class LoadImage {
private ThreadPool.ThreadListener threadListener;
private String url;
private final int readTimeout = 8*1000;
private final int connectTimeout = 8*1000;
private final String requestMethod = "GET";
private InputStream inputStream;
private Callback callback;
public LoadImage(String url, Callback callback){
this.callback = callback;
ThreadPool threadPool = ThreadPool.getInstance();
this.url = url;
threadListener = threadPool.exec(new Runnable() {
@Override
public void run() {
runnableWorker();
}
});
}
private void runnableWorker(){
try {
URL mURL = new URL(url);
HttpURLConnection httpURLConnection = (HttpURLConnection) mURL.openConnection();
httpURLConnection.setRequestMethod(requestMethod);
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setReadTimeout(readTimeout);
httpURLConnection.setConnectTimeout(connectTimeout);
inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
callback.getBitmap(bitmap);
} catch (IOException e) {
callback.getBitmap(null);
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public boolean cancle(){
return threadListener.cancle();
}
public boolean isDone(){
return threadListener.isDone();
}
}
這里我們對(duì)接口拆讯、線程池以及網(wǎng)絡(luò)拉取進(jìn)行二次封裝≈校現(xiàn)在核心的方法我們已經(jīng)封裝完畢养叛,針對(duì)于不同的使用,我們可以再進(jìn)行一層簡(jiǎn)單的封裝調(diào)用宰翅。
使用就非常簡(jiǎn)單了:
new LoadImage("圖片網(wǎng)址", new Callback() {
@Override
public void getBitmap(Bitmap bitmap) {
}
});
筆者能力有限弃甥,不足之處歡迎指出!