안 드 로 이 드 비동기 다운로드 사진 벽
저작권 성명: 본 고 는 ShengFQ 의 블 로그 에서 나 왔 습 니 다. 전재 출처 를 밝 혀 주 십시오.http://www.jianshu.com/p/1709ea24ebbb
나의 문제
서버 에서 그림 주소 목록 을 다운로드 하고 이미지 뷰 에 그림 을 다운로드 하여 캐 시 와 압축 을 실현 하려 고 합 니 다.압축 된 그림 을 다운로드 하려 면 서버 에서 먼저 압축 한 후에 저장 해 야 합 니 다. 여 기 는 클 라 이언 트 범위 만 말 하고 토론 하지 않 습 니 다.
예비 지식 필요: 1. AsyncTask 비동기 호출 방법 json 데이터 2. listview, viewaadapter 의 고성능 쓰기 3. HandlerThread, Hander, Message 비동기 메시지 체제 4. LurCache 캐 시 5. BitmapFactory 의 압축 그림 다운로드
1. AsyncTask 비동기 호출 방법 은 json 데 이 터 를 다운로드 합 니 다. AsyncTask 와 Adapter 조합 은 서버 에서 그림 주 소 를 포함 한 json 형식 데 이 터 를 끌 어 옵 니 다.2. listview, view adapter 의 고성능 쓰기
viewadapter.java
Object mlock;// list , list
Context mContext;//
List datalist;//list
int itemLayoutId;//adapterview id
getDataList();
reload(List models);
add(model model);
addAll(List models);
render(Model model,View view,int position);// ViewHolder getView
getCount();
getItem(int position);
getItemId(int position);
class ViewHolder{}
getView(int position,View convertView,ViewGroup parent);
// view
protected void render(LinkModel linkmodel,View view,int position){
final LinkModel item=linkmodel;
ViewHolder viewHolder=(ViewHolder)view.getTag();
// ,
if(viewHolder==null){
viewHolder=new ViewHolder();
viewHolder.app_layout= (FrameLayout)view.findViewById(R.id.iv_app_layout);
viewHolder.app_icon_layout=(LinearLayout)view.findViewById(R.id.app_icon_layout);
viewHolder.app_log_iv=(ImageView)view.findViewById(R.id.ic_app_ico);
viewHolder.app_name_tv=(TextView)view.findViewById(R.id.ic_app_name);
view.setTag(viewHolder);
}else{
viewHolder=(ViewHolder)view.getTag();
}
if(item!=null){
viewHolder.app_log_iv.setImageResource(R.drawable.app_img_app_normal);
viewHolder.app_name_tv.setText(item.name);
if (ImageCache.getInstance(mCacheSize).isCache(item.photoUrl)) {
viewHolder.app_log_iv.setImageBitmap(ImageCache.getInstance(mCacheSize).getBitmapFromMemCache(item.photoUrl));
}else{
// ,Token imageview
mThumbnailThread.queueThumbnail(viewHolder.app_log_iv, item.photoUrl);
}
}
}
AsyncTask 에서 배경 에 있 는 json 데 이 터 를 실체 대상 에 밀봉 하고 상기 adapter. addAll (List models) 을 통 해 adapter 에 주입 합 니 다.
3. HandlerThread, Hander, Message 비동기 메시지 체 제 는 Thunbnail Downloader 류 를 정의 합 니 다. 다운로드 요청 메 시 지 를 보 내 고 다른 스 레 드 에서 배경 으로 다운로드 하고 프론트 UI 스 레 드 와 의 상호작용 을 통 해 불 러 옵 니 다.
public class ThumbnailDownLoader extends HandlerThread {
private static final String TAG="ThumbnailDownLoader";
private static final int MESSAGE_DOWNLOAD=0;
private Handler mHandler;
private String requestToken;
private int mCacheSize;
Map requestMap= Collections.synchronizedMap(new HashMap());
/**
* Handler
* */
Handler mRespoonseHandler;
//
Listener mListener;
/**
*
* : UI ImageView
* */
public interface Listener{
/**
* , ImageView
* @param token
* @param thumbnail
* */
void onThumbnailDownloaded(Token token,Bitmap thumbnail);
}
public void setListener(Listener listener){
mListener=listener;
}
public ThumbnailDownLoader(String requesttoken){
super(TAG);
this.requestToken=requesttoken;
}
/**
* Handler
* @param responseHandler UI handler
* @param requesttoken token
* @param cacheSize
* */
public ThumbnailDownLoader(Handler responseHandler,String requesttoken,int cacheSize){
super(TAG);
mRespoonseHandler=responseHandler;
this.requestToken=requesttoken;
this.mCacheSize=cacheSize;
}
/**
* Looper
* */
@SuppressLint("handlerLeak")
@Override
protected void onLooperPrepared(){
mHandler=new Handler(){
//looper , what
public void handleMessage(Message msg){
if(msg.what==MESSAGE_DOWNLOAD){
@SuppressWarnings("unchecked")
Token token=(Token)msg.obj;//Handler.obtainMessage(msg,obj); Handler Message message.obj, , obj, 。
Log.i(TAG,"Got a request for url:"+requestMap.get(token));
handleRequest(token,requestToken);
}
}
};
}
/**
* message , URL Token hashMap
* getView()
* @param token UI
* @param url
* */
public void queueThumbnail(Token token,String url){
Log.i(TAG,"Got to URL:"+url);
requestMap.put(token,url);// getview()
Message message=mHandler.obtainMessage(MESSAGE_DOWNLOAD,token);// , handler
message.sendToTarget();//
}
/**
* , UI ImageView
* @param token , ImageView
* */
private void handleRequest(final Token token,final String requestToken){
try{
final String url=requestMap.get(token);
if(url==null)
return;
byte[] bitmapBytes=new ImageLoaderUtils().getUrlBytes(url,requestToken);
// final Bitmap bitmap= BitmapFactory.decodeByteArray(bitmapBytes,0,bitmapBytes.length);
final Bitmap bitmap= ImageCompress.decodeSampleBitmapFromBytes(bitmapBytes, 54, 54);//
ImageCache.getInstance(mCacheSize).addBitmapToMemoryCache(url, bitmap);
Log.i(TAG,"Bitmap created");
// UI
mRespoonseHandler.post(new Runnable(){
public void run(){
if(requestMap.get(token)!=url) return;
requestMap.remove(token);//
Bitmap cachebitmap =ImageCache.getInstance(mCacheSize).getBitmapFromMemCache(url);
if(cachebitmap!=null)
mListener.onThumbnailDownloaded(token,cachebitmap);
else{
mListener.onThumbnailDownloaded(token,bitmap);
}
}
});
}catch(IOException ioe){
Log.e(TAG,"Error downloading image",ioe);
}
}
public void clearQueue(){
mHandler.removeMessages(MESSAGE_DOWNLOAD);
requestMap.clear();
}
}
설명: HandlerThread 는 메시지 알림 처리 스 레 드 클래스 onLooperPrepared (); /Handler 를 초기 화 하 는 곳 입 니 다. Handler Thread 가 초기 화 되면 Loop () 에 들 어가 기 전에 호출 되 는 방법 이기 때 문 입 니 다. Handler 를 초기 화 하 는 것 은 메시지 가 전송 되 기 전에 handler 를 초기 화 하 는 데 도움 이 됩 니 다.
Handler handlleMessage(Message msg);//메시지 의 분류 와 메시지 에 첨부 된 매개 변수 에 따라 handler. obtainMessage (String msg, object) / / Message 대상 message. sendToTarget () 을 비동기 로 다운로드 합 니 다. /메시지 큐 handler. removeMessages (String msg) 에 메 시 지 를 보 냅 니 다. /이 메 시 지 를 지우 고 자원 을 방출 합 니 다.
프론트 UI 스 레 드 와 어떻게 대화 합 니까?
이미 image 를 다운 로드 했 습 니 다. UI 스 레 드 의 Imageview 에 채 우려 면 프론트 데스크 와 상호작용 을 해 야 합 니 다. 맞습니다. 프론트 UI 스 레 드 에 도 Handler 가 있 고 하나 밖 에 없습니다. 프론트 데스크 의 handler 를 백 스테이지 에 전달 하여 공유 합 니 다.
/**
* Handler
*
Handler mRespoonseHandler;
/**
* Handler
* @param responseHandler UI handler
* @param requesttoken token
* @param cacheSize
* */
public ThumbnailDownLoader(Handler responseHandler,String requesttoken,int cacheSize){
super(TAG);
mRespoonseHandler=responseHandler;
this.requestToken=requesttoken;
this.mCacheSize=cacheSize;
}
그림 을 다운로드 한 후 handler. post () 를 통 해방법 과 프론트 UI 상호작용
// UI
mRespoonseHandler.post(new Runnable(){
public void run(){
if(requestMap.get(token)!=url) return;
requestMap.remove(token);//
Bitmap cachebitmap =ImageCache.getInstance(mCacheSize).getBitmapFromMemCache(url);
if(cachebitmap!=null)
mListener.onThumbnailDownloaded(token,cachebitmap);//
else{
mListener.onThumbnailDownloaded(token,bitmap);
}
}
});
Listener mListener;//인터페이스 대상 을 되 돌려 그림 을 다운로드 한 후 그림 을 imageview 에 설정 합 니 다.
/**
*
* : UI ImageView
* */
public interface Listener{
/**
* , ImageView
* @param token
* @param thumbnail
* */
void onThumbnailDownloaded(Token token,Bitmap thumbnail);
}
public void setListener(Listener listener){
mListener=listener;
}
메 인 스 레 드 UI 로 돌아 가기
따라서 UI 스 레 드 에서 두 가지 일 을 하고 HandlerThread 를 초기 화하 여 리 셋 인 터 페 이 스 를 실현 합 니 다.
//
mThumbnailThread = new ThumbnailDownLoader(new Handler(),token,mCacheSize);// Looper Handler
mThumbnailThread.setListener(new ThumbnailDownLoader.Listener() {
public void onThumbnailDownloaded(ImageView imageView, Bitmap thumbnail) {
if (true) {
// ImageView Bitmap
imageView.setImageBitmap(thumbnail);
}
}
});
mThumbnailThread.start();
mThumbnailThread.getLooper();
어떻게 비동기 다운 로드 를 촉발 합 니까
우리 가 실현 하고 자 하 는 효 과 는 gridview 를 끌 어 내 릴 때 그림 을 자동 으로 다운로드 하여 gridview 에 있 는 imageview 보기 로 불 러 오 는 것 입 니 다. 따라서 adapter. getView () 방법 에 초점 을 맞 추 려 면 HandlerThread 의 현재 Imageview 인 스 턴 스 와 다운로드 해 야 할 그림 URL 에 두 개의 중요 한 매개 변수 가 전달 되 어야 합 니 다.
mThumbnailThread.queueThumbnail(viewHolder.app_log_iv, item.photoUrl);
4. LurCache 캐 시 는 주로 LruCache 클래스 를 사 용 했 습 니 다. 이 클래스 의 사용 방법 은 다음 과 같 습 니 다. 일반 캐 시 크기 는 다음 과 같 습 니 다.
UI
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// 1/8 。
mCacheSize = maxMemory / 8;
/**
*
* */
public class ImageCache {
private static ImageCache instance;
/**
* ,
*/
public static ImageCache getInstance(int cacheSize) {
if (instance == null) {
synchronized (ImageCache.class) {
if (instance == null) {
instance = new ImageCache(cacheSize);
}
}
}
return instance;
}
private LruCache mMemoryCache;
private ImageCache(int cacheSize){
mMemoryCache=new LruCache(cacheSize){
protected int sizeOf(String key,Bitmap bitmap){
return bitmap.getByteCount()/1024;
}
};
}
/**
*
* */
public void addBitmapToMemoryCache(String key,Bitmap bitmap){
if(getBitmapFromMemCache(key) ==null){
mMemoryCache.put(key, bitmap);
}
}
/**
*
* */
public Bitmap getBitmapFromMemCache(String key){
return mMemoryCache.get(key);
}
/**
*
* */
public boolean isCache(String key){
Bitmap map=mMemoryCache.get(key);
return map!=null;
}
}
5. BitmapFactory 의 압축 그림
ImageCompress.java
/**
*
* */
public static Bitmap decodeSampleBitmapFromBytes(byte[] data,int reqWidth,int reqHeight){
final BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds=true;
//BitmapFactory.decodeResource(resource, resId, options);
BitmapFactory.decodeByteArray(data, 0, data.length, options);
options.inSampleSize=calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds=false;
return BitmapFactory.decodeByteArray(data, 0, data.length, options);
}
// , inSamplesize,
public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
//
final int height=options.outHeight;
final int width=options.outWidth;
int inSampleSize=1;
if(height>reqHeight || width>reqWidth){
final int heightRatio=Math.round((float)height/(float)reqHeight);
final int widthRatio=Math.round((float)width/(float)reqWidth);
inSampleSize=heightRatio
참고 자료
1.http://blog.csdn.net/guolin_blog / article / details / 9526203 안 드 로 이 드 사진 벽 응용 이 실현 되 었 습 니 다. 아무리 많은 사진 이라도 붕 괴 를 두려워 하지 않 습 니 다.
2 http://blog.csdn.net/guolin_blog / article / details / 9316683 안 드 로 이 드 고 효율 로드 큰 그림, 다 중 그림 솔 루 션, 프로그램 OOM 을 효과적으로 피 할 수 있 습 니 다.
3. android 개발 프로 그래 밍 권위 가이드
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.