鱼C论坛

 找回密码
 立即注册
查看: 2111|回复: 0

异步读取图片到GridView

[复制链接]
发表于 2014-3-16 23:30:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
android设备要求UI线程不能占用太多资源, 而控件资源只能在主线程操作.
因此为了得到更好的用户体验, 在加载和处理大量图片是必须采用多线程技术.



又android的每个应用只能分配到大约16M内存. 因此GridView采用了循环回收的机制, 只有当前屏幕的ImageView中的内容被保存在内存中....

各种限制使得GridView的多线程操作并不简单.


这次网上接单要求GridView如德芙般顺滑....苦逼多日....

终于, 参照android 官方系列教程: http://developer.android.com/training/displaying-bitmaps/display-bitmap.html

实现了多线程GridView的操作:
package com.example.ftp_09;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;






import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore.Images.Media;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class MainActivity extends Activity {

        private GridView gridView;  
         private ArrayList<HashMap<String, String>> list;   
         private ContentResolver cr;
         private ImageView imageview;
         private ArrayList<String> imageSrcs = new ArrayList<String>();
                
         
         
         //private ImageLoader mImageLoader;
         
         
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                findView();
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.main, menu);
                return true;
        }

        private void findView(){
                gridView = (GridView) findViewById(R.id.gridView1); 

                list = new ArrayList<HashMap<String, String>>(); 
                cr = getContentResolver(); 
                String[] projection = { Media.DATA,Media._ID,Media.TITLE,Media.DISPLAY_NAME ,Media.MIME_TYPE }; 
                 Cursor cursor = cr.query(Media.EXTERNAL_CONTENT_URI, projection,  
                        null, null, null);
                 getColumnData(cursor);
                  
        String[] from = { "path","path"};  
        int[] to = { R.id.imageView1 ,R.id.textView1};  
        gridView.setAdapter(new GridAdapter(this));
        //gridView.setAdapter(adapter);  
        gridView.setOnItemClickListener(listener);               
        }
        
    private void getColumnData(Cursor cur) {  
        if (cur.moveToFirst()) {  
             
            String image_path;  
            String image_type;
            int dataColumn = cur.getColumnIndex(Media.DATA);  
            int int_type=cur.getColumnIndexOrThrow(Media.MIME_TYPE);
            do {  
                image_path = cur.getString(dataColumn);  
                image_type=cur.getString(int_type);
                HashMap hash = new HashMap();  
                if(image_type.equals("image/jpeg")){
                        hash.put("path", image_path);
                        hash.put("checked", "no");
                        list.add(hash);
                }
                  
  
            } while (cur.moveToNext());  
  
        }  
    }
        OnItemClickListener listener = new OnItemClickListener() {  
                  
        @Override  
        public void onItemClick(AdapterView<?> parent, View view, int position,  
                long id) {  
                
                Toast.makeText(MainActivity.this, "you chose id: "+id+"\n position: "+position,  
                    Toast.LENGTH_SHORT).show(); 
                TextView txt_show=(TextView)view.findViewById(R.id.textView1);
                
                String image_src = list.get(position).get("path"); 
            txt_show.setText(image_src);
        }  
    }; 
    
    
    class GridAdapter extends BaseAdapter {  
            private Context mContext;
            private LayoutInflater inflater;
            
                public GridAdapter(Context c){
                        mContext=c;
                        inflater=LayoutInflater.from(mContext);
                }
                public int getCount(){
                        return list.size();
                }
                public Object getItem(int position){
                        return null;
                }
                public long getItemId(int position){
                        return 0;
                }
                public View getView(int position, View convertView, ViewGroup parent){
                        //ImageView imageView1;
                        ViewHolder holder=null;
                        if(holder==null){
                                holder = new ViewHolder();
                                convertView = inflater.inflate(R.layout.grid_item, null);
                                holder.image1 = (ImageView)convertView.findViewById(R.id.imageView1);
                                holder.image2 = (ImageView)convertView.findViewById(R.id.imageView2);
                                holder.txt1=(TextView)convertView.findViewById(R.id.textView1);
                                convertView.setTag(holder);
                                
                        }
                        loadBitmap(list.get(position).get("path"), holder.image1);
                        holder.txt1.setText(list.get(position).get("path"));
                        
                        if(list.get(position).get("checked").equals("no")){
                                holder.image2.setVisibility(View.GONE);
                        }else{
                                holder.image2.setVisibility(View.VISIBLE);
                        }
                        
                        return convertView;
                }
                public class ViewHolder{
                        public ImageView image1;     //main view
                        public ImageView image2;     //check view
                        public TextView txt1;                //picture info
                }
                
       
        
    }  
/*
 * 
 * Load PICs to GridView from Files on the SD Card.
 * 
 * 
 * 
 * 
*/
        
        
        public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
        
            if (height > reqHeight || width > reqWidth) {
        
                final int halfHeight = height / 2;
                final int halfWidth = width / 2;
        
                // Calculate the largest inSampleSize value that is a power of 2 and keeps both
                // height and width larger than the requested height and width.
                while ((halfHeight / inSampleSize) > reqHeight
                        && (halfWidth / inSampleSize) > reqWidth) {
                    inSampleSize *= 2;
                }
            }
        
            return inSampleSize;
        }
        public static Bitmap decodeBitmapFromFile(String Uri,int reqWidth, int reqHeight){
                final BitmapFactory.Options options=new BitmapFactory.Options();
                options.inJustDecodeBounds=true;
                //获得图片大小信息
                BitmapFactory.decodeFile(Uri, options);
                
                //计算 inSampleSize
                 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

                // Decode bitmap with inSampleSize set
                options.inJustDecodeBounds = false;
                return Bitmap.createScaledBitmap(BitmapFactory.decodeFile(Uri, options), 200, 200, true);  
        
                 
                
                
                //return BitmapFactory.decodeFile(Uri);
        }
        public void loadBitmap(String pic_uri, ImageView imageView) {
            if (cancelPotentialWork(pic_uri, imageView)) {
                final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
                final AsyncDrawable asyncDrawable =
                        new AsyncDrawable(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), task);
                imageView.setImageDrawable(asyncDrawable);
                task.execute(pic_uri);
            }
        }
        
        public static boolean cancelPotentialWork(String data, ImageView imageView) {
            final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

            if (bitmapWorkerTask != null) {
               // final int bitmapData = bitmapWorkerTask.data;
                    final String bitmapUri=bitmapWorkerTask.uri;
                // If bitmapData is not yet set or it differs from the new data
                if (bitmapUri.equals("")|| (!bitmapUri.equals(data))) {
                    // Cancel previous task
                    bitmapWorkerTask.cancel(true);
                } else {
                    // The same work is already in progress
                    return false;
                }
            }
            // No task associated with the ImageView, or an existing task was cancelled
            return true;
        }
        
        private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
                   if (imageView != null) {
                       final Drawable drawable = imageView.getDrawable();
                       if (drawable instanceof AsyncDrawable) {
                           final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
                           return asyncDrawable.getBitmapWorkerTask();
                       }
                    }
                    return null;
                }
        
        
        
        class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {

                private final WeakReference<ImageView> imageViewReference;
                private String uri="";
            public BitmapWorkerTask(ImageView imageView) {
                // Use a WeakReference to ensure the ImageView can be garbage collected
                imageViewReference = new WeakReference<ImageView>(imageView);
            }

            // Decode image in background.
            @Override
            protected Bitmap doInBackground(String... uris) {
                //data = params[0];
                    uri=uris[0];
                    //change to decode from files.
                //return decodeSampledBitmapFromResource(getResources(), data, 100, 100);
                    return decodeBitmapFromFile(uri, 200, 200);
            }

            // Once complete, see if ImageView is still around and set bitmap.
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                    if (isCancelled()) {
                    bitmap = null;
                }
                    
                if (imageViewReference != null && bitmap != null) {
                    final ImageView imageView = imageViewReference.get();
                    final BitmapWorkerTask bitmapWorkerTask =
                            getBitmapWorkerTask(imageView);
                    if (this == bitmapWorkerTask && imageView != null) {
                            //放置图片到Item
                        imageView.setImageBitmap(bitmap);
                    }
                }
            }
            

        }

        static class AsyncDrawable extends BitmapDrawable{

                private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

            public AsyncDrawable(Resources res, Bitmap bitmap,
                    BitmapWorkerTask bitmapWorkerTask) {
                super(res, bitmap);
                bitmapWorkerTaskReference =
                    new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
            }

            public BitmapWorkerTask getBitmapWorkerTask() {
                return bitmapWorkerTaskReference.get();
            }
        }

}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <GridView
        android:id="@+id/gridView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:numColumns="3" >

    </GridView>

</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        
        
         <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

             

         <ImageView
        android:id="@+id/imageView1"
        android:layout_width="200px"
        android:layout_height="200px"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />
        
    </LinearLayout>
    
         <ImageView
             android:id="@+id/imageView2"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="top|left"
             android:src="@android:drawable/checkbox_on_background" />
         
    </FrameLayout>

  

</LinearLayout>
闲来无聊贴上一部分...

休息一下, 继续实现FTP上传功能...
敬请期待...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 11:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表