鱼C论坛

 找回密码
 立即注册
查看: 2213|回复: 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的操作:

  1. package com.example.ftp_09;

  2. import java.lang.ref.WeakReference;
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;






  7. import android.net.Uri;
  8. import android.os.AsyncTask;
  9. import android.os.Bundle;
  10. import android.provider.MediaStore.Images.Media;
  11. import android.app.Activity;
  12. import android.content.ContentResolver;
  13. import android.content.Context;
  14. import android.content.Intent;
  15. import android.content.res.Resources;
  16. import android.database.Cursor;
  17. import android.graphics.Bitmap;
  18. import android.graphics.BitmapFactory;
  19. import android.graphics.drawable.BitmapDrawable;
  20. import android.graphics.drawable.Drawable;
  21. import android.util.Log;
  22. import android.view.LayoutInflater;
  23. import android.view.Menu;
  24. import android.view.View;
  25. import android.view.ViewGroup;
  26. import android.widget.AdapterView;
  27. import android.widget.BaseAdapter;
  28. import android.widget.Button;
  29. import android.widget.GridView;
  30. import android.widget.ImageView;
  31. import android.widget.ListAdapter;
  32. import android.widget.SimpleAdapter;
  33. import android.widget.TextView;
  34. import android.widget.Toast;
  35. import android.widget.AdapterView.OnItemClickListener;

  36. public class MainActivity extends Activity {

  37.         private GridView gridView;  
  38.          private ArrayList<HashMap<String, String>> list;   
  39.          private ContentResolver cr;
  40.          private ImageView imageview;
  41.          private ArrayList<String> imageSrcs = new ArrayList<String>();
  42.                
  43.          
  44.          
  45.          //private ImageLoader mImageLoader;
  46.          
  47.          
  48.         @Override
  49.         protected void onCreate(Bundle savedInstanceState) {
  50.                 super.onCreate(savedInstanceState);
  51.                 setContentView(R.layout.activity_main);
  52.                 findView();
  53.         }

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

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

  62.                 list = new ArrayList<HashMap<String, String>>();
  63.                 cr = getContentResolver();
  64.                 String[] projection = { Media.DATA,Media._ID,Media.TITLE,Media.DISPLAY_NAME ,Media.MIME_TYPE };
  65.                  Cursor cursor = cr.query(Media.EXTERNAL_CONTENT_URI, projection,  
  66.                         null, null, null);
  67.                  getColumnData(cursor);
  68.                   
  69.         String[] from = { "path","path"};  
  70.         int[] to = { R.id.imageView1 ,R.id.textView1};  
  71.         gridView.setAdapter(new GridAdapter(this));
  72.         //gridView.setAdapter(adapter);  
  73.         gridView.setOnItemClickListener(listener);               
  74.         }
  75.        
  76.     private void getColumnData(Cursor cur) {  
  77.         if (cur.moveToFirst()) {  
  78.             
  79.             String image_path;  
  80.             String image_type;
  81.             int dataColumn = cur.getColumnIndex(Media.DATA);  
  82.             int int_type=cur.getColumnIndexOrThrow(Media.MIME_TYPE);
  83.             do {  
  84.                 image_path = cur.getString(dataColumn);  
  85.                 image_type=cur.getString(int_type);
  86.                 HashMap hash = new HashMap();  
  87.                 if(image_type.equals("image/jpeg")){
  88.                         hash.put("path", image_path);
  89.                         hash.put("checked", "no");
  90.                         list.add(hash);
  91.                 }
  92.                   
  93.   
  94.             } while (cur.moveToNext());  
  95.   
  96.         }  
  97.     }
  98.         OnItemClickListener listener = new OnItemClickListener() {  
  99.                   
  100.         @Override  
  101.         public void onItemClick(AdapterView<?> parent, View view, int position,  
  102.                 long id) {  
  103.                
  104.                 Toast.makeText(MainActivity.this, "you chose id: "+id+"\n position: "+position,  
  105.                     Toast.LENGTH_SHORT).show();
  106.                 TextView txt_show=(TextView)view.findViewById(R.id.textView1);
  107.                
  108.                 String image_src = list.get(position).get("path");
  109.             txt_show.setText(image_src);
  110.         }  
  111.     };
  112.    
  113.    
  114.     class GridAdapter extends BaseAdapter {  
  115.             private Context mContext;
  116.             private LayoutInflater inflater;
  117.            
  118.                 public GridAdapter(Context c){
  119.                         mContext=c;
  120.                         inflater=LayoutInflater.from(mContext);
  121.                 }
  122.                 public int getCount(){
  123.                         return list.size();
  124.                 }
  125.                 public Object getItem(int position){
  126.                         return null;
  127.                 }
  128.                 public long getItemId(int position){
  129.                         return 0;
  130.                 }
  131.                 public View getView(int position, View convertView, ViewGroup parent){
  132.                         //ImageView imageView1;
  133.                         ViewHolder holder=null;
  134.                         if(holder==null){
  135.                                 holder = new ViewHolder();
  136.                                 convertView = inflater.inflate(R.layout.grid_item, null);
  137.                                 holder.image1 = (ImageView)convertView.findViewById(R.id.imageView1);
  138.                                 holder.image2 = (ImageView)convertView.findViewById(R.id.imageView2);
  139.                                 holder.txt1=(TextView)convertView.findViewById(R.id.textView1);
  140.                                 convertView.setTag(holder);
  141.                                
  142.                         }
  143.                         loadBitmap(list.get(position).get("path"), holder.image1);
  144.                         holder.txt1.setText(list.get(position).get("path"));
  145.                        
  146.                         if(list.get(position).get("checked").equals("no")){
  147.                                 holder.image2.setVisibility(View.GONE);
  148.                         }else{
  149.                                 holder.image2.setVisibility(View.VISIBLE);
  150.                         }
  151.                        
  152.                         return convertView;
  153.                 }
  154.                 public class ViewHolder{
  155.                         public ImageView image1;     //main view
  156.                         public ImageView image2;     //check view
  157.                         public TextView txt1;                //picture info
  158.                 }
  159.                
  160.       
  161.         
  162.     }  
  163. /*
  164. *
  165. * Load PICs to GridView from Files on the SD Card.
  166. *
  167. *
  168. *
  169. *
  170. */
  171.        
  172.        
  173.         public static int calculateInSampleSize(
  174.             BitmapFactory.Options options, int reqWidth, int reqHeight) {
  175.     // Raw height and width of image
  176.     final int height = options.outHeight;
  177.     final int width = options.outWidth;
  178.     int inSampleSize = 1;
  179.        
  180.             if (height > reqHeight || width > reqWidth) {
  181.        
  182.                 final int halfHeight = height / 2;
  183.                 final int halfWidth = width / 2;
  184.        
  185.                 // Calculate the largest inSampleSize value that is a power of 2 and keeps both
  186.                 // height and width larger than the requested height and width.
  187.                 while ((halfHeight / inSampleSize) > reqHeight
  188.                         && (halfWidth / inSampleSize) > reqWidth) {
  189.                     inSampleSize *= 2;
  190.                 }
  191.             }
  192.        
  193.             return inSampleSize;
  194.         }
  195.         public static Bitmap decodeBitmapFromFile(String Uri,int reqWidth, int reqHeight){
  196.                 final BitmapFactory.Options options=new BitmapFactory.Options();
  197.                 options.inJustDecodeBounds=true;
  198.                 //获得图片大小信息
  199.                 BitmapFactory.decodeFile(Uri, options);
  200.                
  201.                 //计算 inSampleSize
  202.                  options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

  203.                 // Decode bitmap with inSampleSize set
  204.                 options.inJustDecodeBounds = false;
  205.                 return Bitmap.createScaledBitmap(BitmapFactory.decodeFile(Uri, options), 200, 200, true);  
  206.         
  207.                  
  208.                
  209.                
  210.                 //return BitmapFactory.decodeFile(Uri);
  211.         }
  212.         public void loadBitmap(String pic_uri, ImageView imageView) {
  213.             if (cancelPotentialWork(pic_uri, imageView)) {
  214.                 final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
  215.                 final AsyncDrawable asyncDrawable =
  216.                         new AsyncDrawable(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), task);
  217.                 imageView.setImageDrawable(asyncDrawable);
  218.                 task.execute(pic_uri);
  219.             }
  220.         }
  221.        
  222.         public static boolean cancelPotentialWork(String data, ImageView imageView) {
  223.             final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

  224.             if (bitmapWorkerTask != null) {
  225.                // final int bitmapData = bitmapWorkerTask.data;
  226.                     final String bitmapUri=bitmapWorkerTask.uri;
  227.                 // If bitmapData is not yet set or it differs from the new data
  228.                 if (bitmapUri.equals("")|| (!bitmapUri.equals(data))) {
  229.                     // Cancel previous task
  230.                     bitmapWorkerTask.cancel(true);
  231.                 } else {
  232.                     // The same work is already in progress
  233.                     return false;
  234.                 }
  235.             }
  236.             // No task associated with the ImageView, or an existing task was cancelled
  237.             return true;
  238.         }
  239.        
  240.         private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
  241.                    if (imageView != null) {
  242.                        final Drawable drawable = imageView.getDrawable();
  243.                        if (drawable instanceof AsyncDrawable) {
  244.                            final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
  245.                            return asyncDrawable.getBitmapWorkerTask();
  246.                        }
  247.                     }
  248.                     return null;
  249.                 }
  250.        
  251.        
  252.        
  253.         class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {

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

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

  269.             // Once complete, see if ImageView is still around and set bitmap.
  270.             @Override
  271.             protected void onPostExecute(Bitmap bitmap) {
  272.                     if (isCancelled()) {
  273.                     bitmap = null;
  274.                 }
  275.                    
  276.                 if (imageViewReference != null && bitmap != null) {
  277.                     final ImageView imageView = imageViewReference.get();
  278.                     final BitmapWorkerTask bitmapWorkerTask =
  279.                             getBitmapWorkerTask(imageView);
  280.                     if (this == bitmapWorkerTask && imageView != null) {
  281.                             //放置图片到Item
  282.                         imageView.setImageBitmap(bitmap);
  283.                     }
  284.                 }
  285.             }
  286.             

  287.         }

  288.         static class AsyncDrawable extends BitmapDrawable{

  289.                 private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

  290.             public AsyncDrawable(Resources res, Bitmap bitmap,
  291.                     BitmapWorkerTask bitmapWorkerTask) {
  292.                 super(res, bitmap);
  293.                 bitmapWorkerTaskReference =
  294.                     new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
  295.             }

  296.             public BitmapWorkerTask getBitmapWorkerTask() {
  297.                 return bitmapWorkerTaskReference.get();
  298.             }
  299.         }

  300. }
复制代码

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:paddingBottom="@dimen/activity_vertical_margin"
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"
  7.     android:paddingRight="@dimen/activity_horizontal_margin"
  8.     android:paddingTop="@dimen/activity_vertical_margin"
  9.     tools:context=".MainActivity" >

  10.     <GridView
  11.         android:id="@+id/gridView1"
  12.         android:layout_width="fill_parent"
  13.         android:layout_height="fill_parent"
  14.         android:layout_alignParentBottom="true"
  15.         android:layout_alignParentLeft="true"
  16.         android:layout_alignParentRight="true"
  17.         android:layout_alignParentTop="true"
  18.         android:numColumns="3" >

  19.     </GridView>

  20. </RelativeLayout>
复制代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:orientation="vertical" >

  6.     <FrameLayout
  7.         android:layout_width="match_parent"
  8.         android:layout_height="wrap_content" >
  9.         
  10.         
  11.          <LinearLayout
  12.         android:layout_width="match_parent"
  13.         android:layout_height="wrap_content"
  14.         android:orientation="vertical" >

  15.             

  16.          <ImageView
  17.         android:id="@+id/imageView1"
  18.         android:layout_width="200px"
  19.         android:layout_height="200px"
  20.         android:src="@drawable/ic_launcher" />

  21.     <TextView
  22.         android:id="@+id/textView1"
  23.         android:layout_width="wrap_content"
  24.         android:layout_height="wrap_content"
  25.         android:text="TextView" />
  26.         
  27.     </LinearLayout>
  28.    
  29.         <ImageView
  30.             android:id="@+id/imageView2"
  31.             android:layout_width="wrap_content"
  32.             android:layout_height="wrap_content"
  33.             android:layout_gravity="top|left"
  34.             android:src="@android:drawable/checkbox_on_background" />
  35.        
  36.     </FrameLayout>

  37.   

  38. </LinearLayout>
复制代码
闲来无聊贴上一部分...

休息一下, 继续实现FTP上传功能...
敬请期待...
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-28 02:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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