做了個工具方法,用來下載圖片,如果本地有這個圖,則不下載,直接展示到view
setHP()方法可以多次使用,因為使用了線程池,所以是個異步操作,如果使用的多,建議根據需要增加線程池的線程數量
看代碼:參數為線程數,自定義設置
//線程池
private ExecutorService executorService = Executors.newFixedThreadPool(2);
//具體方法,參數:第一個是服務器需要下載的文件名(圖片名),第二個是要展示的view,已經實例化,這里不展示
void setHP(String filename, de.hdodenhof.circleimageview.CircleImageView cde) {
executorService.submit(new Runnable() {
@Override
public void run() {
// 判斷本地是否有該圖片
//本地存放圖片的具體路徑
String mfileName = Objects.requireNonNull(getContext()).getExternalCacheDir() + "/paipaixiu/" + filename;
File file = new File(mfileName);
//判斷是否存在
if (file.exists() && !file.isDirectory()) {
//存在,直接加載
//不需要判斷Android版本
try {
//直接由真實路徑加載,轉換成bitmap類型
Bitmap bitmap = BitmapFactory.decodeFile(mfileName);
Objects.requireNonNull(getActivity()).runOnUiThread(new Runnable() {
@Override
public void run() {
//展示到想要的view,即第二個參數
cde.setImageBitmap(bitmap);
}
});
} catch (Exception e) {
file.delete();
}
} else {
//本地不存在,需要從服務器下載
OkHttpClient client = new OkHttpClient();
Request request;
Response response;
//參數u是該圖片在服務器的具體網址路徑,我已經提前處理好了,這里就不展示了,
String u = url2 + "/" + filename;
request = new Request.Builder()
.url(u)
.build();
try {
response = client.newCall(request).execute();
//返回的結果
final byte[] bytes = response.body().bytes();
//在子線程轉換,減少負擔,二進制流轉換成bitmap類型
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Objects.requireNonNull(getActivity()).runOnUiThread(new Runnable() {
@Override
public void run() {
//展示到想要的view,即第二個參數
cde.setImageBitmap(bitmap);
}
});
//保存下載好的文件到本地,要在線程里進行保存,Android里創建文件,必須先存在文件夾才能創建文件,需要逐步確認才可以,這個坑,花了我大半天時間才搞清楚
//先判斷文件夾是否存在,不存在才新建用mkdirs();,可以新建多級文件夾
File fd = new File(Objects.requireNonNull(getContext()).getExternalCacheDir() + "/paipaixiu");
if (!fd.exists() || !fd.isDirectory()) {
fd.mkdirs();
}
//然后判斷文件是否存在,不存在才新建,用createNewFile();,僅僅用來新建文件夾
File fp = new File(fd + "/" + filename);
if (!fp.exists()) {
fp.createNewFile();
}
//只有文件新建好了,才可以使用使字符流保存到文件里,這里保存的是個.png圖片
//開啟字符流
FileOutputStream fos = new FileOutputStream(fp);
//寫入
fos.write(bytes, 0, bytes.length);
//結束寫入
fos.flush();
//關閉字符流
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}