为了账号安全,请及时绑定邮箱和手机立即绑定

使用Asynctask的方法加载图片非常的慢

通过log我发现从new newAsynctask(image,url).execute(url);开始到加载图片需要很长时间,而thread方法则很快,不是网络的问题,是什么问题呢

package com.example.asynvtask_learn;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;

class Imageload{
	private ImageView image;
	private String url;
	private LruCache<String, Bitmap> mcache;//用于缓存
	private Handler mhandler = new Handler(){
		public void handleMessage(Message msg) {
			if(image.getTag().equals(url)){
				image.setImageBitmap((Bitmap) msg.obj
			);}
		};
	};
	
	public Imageload() {
		// TODO Auto-generated constructor stub
		//缓存
		int maxMemory=(int) Runtime.getRuntime().maxMemory();//获取最大内存
		int Memorysize=maxMemory/4;
		mcache=new LruCache<String, Bitmap>(Memorysize){
			@Override
			protected int sizeOf(String key, Bitmap value) {
				// TODO Auto-generated method stub
				return value.getByteCount();//Bitmap的大小
			}
		};
		//缓存
	}
	//加入缓存
	public void addbitmaptocache(String url,Bitmap bitmap){
		if(getbitmapfromcache(url)==null){
			mcache.put(url, bitmap);
		}
	}
	//获取缓存
	public Bitmap getbitmapfromcache(String url) {
		Bitmap mbitmap=mcache.get(url);
		return mbitmap;
	}
	
	public Bitmap getbitmap(String surl){
		Bitmap bitmap = null;
		InputStream is = null;
		try {
			URL url=new URL(surl);
			HttpURLConnection htc=(HttpURLConnection) url.openConnection();
			is=new BufferedInputStream(htc.getInputStream());
			bitmap=BitmapFactory.decodeStream(is);
			htc.disconnect();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				is.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return bitmap;
		
	}
	
	//thread方法
	public void showimagebythread(ImageView image,final String url){
		this.image=image;
		this.url=url;
		new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
				Bitmap bt=getbitmap(url);
				Message message = Message.obtain();
				message.obj=bt;
				mhandler.sendMessage(message);
				
			}
		}.start();
	}
	//asynctask方法
	public void showimagebyasynctask(ImageView image,String url){
		Bitmap bitmap=getbitmapfromcache(url);//缓存中取出图片
		Log.i("info", "取出了缓存");
		if(bitmap==null){
			//如果没有则要去下载
			new newAsynctask(image,url).execute(url);
			Log.i("info", "下载");
		}else{
			image.setImageBitmap(bitmap);
			Log.i("info", "缓存加载");
		}
		
	}
	
	class newAsynctask extends AsyncTask<String, Void, Bitmap>{
		String url;
		ImageView imageView;
		public newAsynctask(ImageView imageView,String url) {
			// TODO Auto-generated constructor stub
			this.imageView=imageView;
			this.url=url;
		}
		
		@Override
		protected Bitmap doInBackground(String... params) {
			// TODO Auto-generated method stub
			String murl=params[0];
			Bitmap bitmap=getbitmap(murl);
			if(bitmap!=null){
				//加入缓存
				addbitmaptocache(murl,bitmap);
				Log.i("info", "加入了缓存");
			}
			return bitmap;
//			return getbitmap(params[0]);
		}
		
		@Override
		protected void onPostExecute(Bitmap result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			if(imageView.getTag().equals(url)){
				imageView.setImageBitmap(result);
				Log.i("info", "下载加载");
			}
		}
	}
}


正在回答

3 回答

你的Thread实现中好像没有调用addbitmaptocache

而asynctask你试试用executeOnExecutor();第一个参数你提前创建一个线程池对象,调用的时候传入。

0 回复 有任何疑惑可以回复我~
#1

不要摸我尾巴喵 提问者

用你的方法果然快了超多,可是为什么没有用到缓存我还是没找到原因...
2015-06-11 回复 有任何疑惑可以回复我~
#2

不要摸我尾巴喵 提问者

非常感谢!原来我每次都new了一个LruCache
2015-06-11 回复 有任何疑惑可以回复我~
#3

orangesweet 回复 不要摸我尾巴喵 提问者

恩,曾经也用execute方法,因为cpu很忙,等10秒执行,当时不知道为什么,后来才知execute方法执行的策略就是这样,这涉及源码了,我没研究过,知道大概。executeOnExecutor从线程池中获取线程执行方法,优先级比较高。 按你说的你应该是每次读图都创建ImageLoad对象,那你LruCache最好弄成单例的,可以在Application中创建。或者ImageLoad弄成单例,把每个imageview放到message中。网络读图有很多框架,volley,universImageLoader等等,实际使用这些框架很方便,不用自己写,这例子当学习AsyncTask就行了
2015-06-12 回复 有任何疑惑可以回复我~

怎么解决的啊?

0 回复 有任何疑惑可以回复我~

而且发现并没有用到缓存..什么情况

0 回复 有任何疑惑可以回复我~
#1

0我是既然0

仔细检查下方法的调用,有可能你把getBitmapfrommCaches写成了getBitmapFromURL之类的
2015-07-26 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
Android必学-异步加载
  • 参与学习       50627    人
  • 解答问题       311    个

了解Android中的异步加载处理方法,这是面试问的最多的知识点

进入课程

使用Asynctask的方法加载图片非常的慢

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信