通过修改教程代码来尝试不同的工作来学习。我现在还处于严肃的学习阶段,请原谅这个问题,如果它听起来无知。我有以下代码,我正在通过解析的XML文件(从教程/示例)下载图像文件:
public class ImageDownloader {
Map<String,Bitmap> imageCache;
public ImageDownloader(){
imageCache = new HashMap<String, Bitmap>();
}
//download function
public void download(String url, ImageView imageView) {
if (cancelPotentialDownload(url, imageView)) {
//Caching code right here
String filename = url.substring(url.lastIndexOf('/') + 1);
File f = new File(getCacheDirectory(imageView.getContext()), filename);
// Is the bitmap in our memory cache?
Bitmap bitmap = null;
bitmap = (Bitmap)imageCache.get(f.getPath());
if(bitmap == null){
bitmap = BitmapFactory.decodeFile(f.getPath());
if(bitmap != null){
imageCache.put(f.getPath(), bitmap);
}
}
//No? download it
if(bitmap == null){
BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
imageView.setImageDrawable(downloadedDrawable);
task.execute(url);
}else{
//Yes? set the image
imageView.setImageBitmap(bitmap);
}
}
}
//cancel a download (internal only)
private static boolean cancelPotentialDownload(String url, ImageView imageView) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
if (bitmapDownloaderTask != null) {
String bitmapUrl = bitmapDownloaderTask.url;
if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
bitmapDownloaderTask.cancel(true);
} else {
// The same URL is already being downloaded.
return false;
}
}
return true;
}
//gets an existing download if one exists for the imageview
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
//our caching functions
// Find the dir to save cached images
private static File getCacheDirectory(Context context){
String sdState = android.os.Environment.getExternalStorageState();
File cacheDir;
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
File sdDir = android.os.Environment.getExternalStorageDirectory();
//TODO : Change your diretcory here
cacheDir = new File(sdDir,"data/fresh/images");
}
else
cacheDir = context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
return cacheDir;
}
private void writeFile(Bitmap bmp, File f) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 80, out);
} catch (Exception e) {
e.printStackTrace();
}
finally {
try { if (out != null ) out.close(); }
catch(Exception ex) {}
}
}
///////////////////////
//download asynctask
public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
url = (String)params[0];
return downloadBitmap(params[0]);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
// Change bitmap only if this process is still associated with it
if (this == bitmapDownloaderTask) {
imageView.setImageBitmap(bitmap);
//cache the image
String filename = url.substring(url.lastIndexOf('/') + 1);
//String filename = String.valueOf(url.hashCode());
File f = new File(getCacheDirectory(imageView.getContext()), filename);
imageCache.put(f.getPath(), bitmap);
writeFile(bitmap, f);
}
}
}
}
static class DownloadedDrawable extends ColorDrawable {
private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
super(Color.BLACK);
bitmapDownloaderTaskReference =
new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
}
}
//the actual download code
static Bitmap downloadBitmap(String url) {
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
// Could provide a more explicit error message for IOException or IllegalStateException
getRequest.abort();
Log.w("ImageDownloader", "Error while retrieving bitmap from " + url + e.toString());
} finally {
if (client != null) {
//client.close();
}
}
return null;
}
}
然后我有一个列表视图,其中包含以下代码以获取图像:
String uri = "drawable/"+ downloadedImgs.get(position).get(KEY_ICON);
int imageResource = holwtt.getContext().getApplicationContext().getResources().getIdentifier(uri, null, holwtt.getContext().getApplicationContext().getPackageName());
Drawable image = holwtt.getContext().getResources().getDrawable(imageResource);
holder.firstImg.setImageDrawable(image);
我想我明白使用getResources()
并不是我访问图片所需要的。问题是我尝试过的一切都不起作用,getPath()
等。
图像将在应用程序中使用,但会更改,因此在apk中包含它们不是一个选项。还试图考虑是否安装了SD卡,因此存在不使用硬编码目录路径的问题。
我感谢您的建议和意见。
答案 0 :(得分:0)
在这段代码中有很多东西是不对的。 当你正在学习时,我会给你一些示例代码,这样你就可以开始并让你继续学习更好的方向。请注意,根据Android文档的建议,可以使用HttpUrlConnection而不是HttpClient来改进您的代码。另请注意,图像的url会转换为整数哈希,因此您可以将其用作文件的名称。也可以使用内部或外部存储。这只是AsyncTask,我希望你多挖一点,然后自己创建图像适配器。继续!
public static class ImageCacher extends AsyncTask<String, String, Integer>{
Context context;
ImageView iv;
Bitmap b;
public ImageCacher(Context context, ImageView iv){
this.context = context;
this.iv = iv;
}
@Override
protected Integer doInBackground(String... params) {
for(String p:params){
//Modification to get relative urls
final String param;
if(!p.startsWith("http")){
param = URL_BASE+p;
}else{
param = p;
}
//check if already CACHED
File file = getFileForCachedImage(param);
b = getCachedImage(file);
if(b != null){
if(iv != null){
iv.post(new Runnable() {
public void run() {
String tag = (String) iv.getTag();
if(tag != null){
if(tag.matches(param))
iv.setImageBitmap(b);
}
}
});
}
return 0;
}else{
file.delete();
}
//download
//file = new File(context.getFilesDir(), filename); //OLD way
file = getFileForCachedImage(param);
b = saveImageFromUrl(context, param);
if(b != null){
if(iv != null){
iv.post(new Runnable() {
public void run() {
String tag = (String) iv.getTag();
if(tag != null){
if(tag.matches(param))
iv.setImageBitmap(b);
}
}
});
}
}
}
return 0;
}
}
/**
* Gets an image given its url
* @param param
*/
public static Bitmap saveImageFromUrl(Context context, String fullUrl) {
Bitmap b = null;
try {
URL url = new URL(fullUrl);
URLConnection conn = url.openConnection();
conn.setDoInput(true);
conn.connect();
//save bitmap to file
InputStream is = conn.getInputStream();
//String filename = String.format("%d", fullUrl.hashCode()); //ORIGINAL way
//File file = new File(context.getFilesDir(), filename); //original way
File file = getFileForCachedImage(fullUrl);
if(file.exists()){
//delete
file.delete();
file=null;
}
//file = new File(context.getFilesDir(), filename); //ORIGINAL way
file = getFileForCachedImage(fullUrl);
FileOutputStream out = new FileOutputStream(file);
byte buffer[] = new byte[256];
while(true){
int cnt = is.read(buffer);
if(cnt <=0){
break;
}
out.write(buffer,0, cnt);
}
out.flush();
out.close();
is.close();
b = BitmapFactory.decodeFile(file.getAbsolutePath());
} catch (Exception e) {
// e.printStackTrace();
}
return b;
}
/**
* Gets the file to cache the image
* @param url
* @return
*/
public static File getFileForCachedImage(String url) {
/**
* Modification for relative urls
*/
if(!url.startsWith("http")){
url = URL_BASE+url;
}
String filename = String.format("%d.cached", url.hashCode());
/**
* External storage
*/
File file = new File(Environment.getExternalStorageDirectory(), EXT_DIR_NAME+"/"+filename); //EXTERNAL storage
String parent = file.getParent();
if(parent != null){
new File(parent).mkdirs();
}
/**
* Internal storage
*/
//File file = new File(context.getFilesDir(), filename); //INTERNAL storage
return file;
}
/**
* Returns a bitmap object if cached
* @param file
* @return
*/
public static Bitmap getCachedImage(File file) {
try {
return BitmapFactory.decodeFile(file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}