Android App中实现图片异步加载的实例分享

论坛 期权论坛 脚本     
niminba   2021-5-23 04:03   2770   0

一、概述
一般大量图片的加载,比如GridView实现手机的相册功能,一般会用到LruCache,线程池,任务队列等;那么异步消息处理可以用哪呢?
1、用于UI线程当Bitmap加载完成后更新ImageView
2、在图片加载类初始化时,我们会在一个子线程中维护一个Loop实例,当然子线程中也就有了MessageQueue,Looper会一直在那loop停着等待消息的到达,当有消息到达时,从任务队列按照队列调度的方式(FIFO,LIFO等),取出一个任务放入线程池中进行处理。
简易的一个流程:当需要加载一张图片,首先把加载图片加入任务队列,然后使用loop线程(子线程)中的hander发送一个消息,提示有任务到达,loop()(子线程)中会接着取出一个任务,去加载图片,当图片加载完成,会使用UI线程的handler发送一个消息去更新UI界面。
说了这么多,大家估计也觉得云里来雾里去的,下面看实际的例子。

二、图库功能的实现
该程序首先扫描手机中所有包含图片的文件夹,最终选择图片最多的文件夹,使用GridView显示其中的图片

1、布局文件

<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" > 
 
 <GridView 
  android:id="@+id/id_gridView" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:cacheColorHint="@android:color/transparent" 
  android:columnWidth="90dip" 
  android:gravity="center" 
  android:horizontalSpacing="20dip" 
  android:listSelector="@android:color/transparent" 
  android:numColumns="auto_fit" 
  android:stretchMode="columnWidth" 
  android:verticalSpacing="20dip" > 
 </GridView> 
 
</RelativeLayout> 

布局文件相当简单就一个GridView
2、MainActivity

package com.example.zhy_handler_imageloader; 
 
import java.io.File; 
import java.io.FilenameFilter; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.List; 
 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.ContentResolver; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Environment; 
import android.os.Handler; 
import android.provider.MediaStore; 
import android.widget.GridView; 
import android.widget.ImageView; 
import android.widget.ListAdapter; 
import android.widget.Toast; 
 
public class MainActivity extends Activity 
{ 
 private ProgressDialog mProgressDialog; 
 private ImageView mImageView; 
  
 /** 
  * 存储文件夹中的图片数量 
  */ 
 private int mPicsSize; 
 /** 
  * 图片数量最多的文件夹 
  */ 
 private File mImgDir; 
 /** 
  * 所有的图片 
  */ 
 private List<String> mImgs; 
 
 private GridView mGirdView; 
 private ListAdapter mAdapter; 
 /** 
  * 临时的辅助类,用于防止同一个文件夹的多次扫描 
  */ 
 private HashSet<String> mDirPaths = new HashSet<String>(); 
 
 private Handler mHandler = new Handler() 
 { 
  public void handleMessage(android.os.Message msg) 
  { 
   mProgressDialog.dismiss(); 
   mImgs = Arrays.asList(mImgDir.list(new FilenameFilter() 
   { 
    @Override 
    public boolean accept(File dir, String filename) 
    { 
     if (filename.endsWith(".jpg")) 
      return true; 
     return false; 
    } 
   })); 
   /** 
    * 可以看到文件夹的路径和图片的路径分开保存,极大的减少了内存的消耗; 
    */ 
   mAdapter = new MyAdapter(getApplicationContext(), mImgs, 
     mImgDir.getAbsolutePath()); 
   mGirdView.setAdapter(mAdapter); 
  }; 
 }; 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) 
 { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
  mGirdView = (GridView) findViewById(R.id.id_gridView); 
  getImages(); 
 
 } 
 
 /** 
  * 利用ContentProvider扫描手机中的图片,此方法在运行在子线程中 完成图片的扫描,最终获得jpg最多的那个文件夹 
  */ 
 private void getImages() 
 { 
  if (!Environment.getExternalStorageState().equals( 
    Environment.MEDIA_MOUNTED)) 
  { 
   Toast.makeText(this, "暂无外部存储", Toast.LENGTH_SHORT).show(); 
   return; 
  } 
  // 显示进度条 
  mProgressDialog = ProgressDialog.show(this, null, "正在加载..."); 
 
  new Thread(new Runnable() 
  { 
 
   @Override 
   public void run() 
   { 
    Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 
    ContentResolver mContentResolver = MainActivity.this 
      .getContentResolver(); 
 
    // 只查询jpeg和png的图片 
    Cursor mCursor = mContentResolver.query(mImageUri, null, 
      MediaStore.Images.Media.MIME_TYPE + "=? or " 
        + MediaStore.Images.Media.MIME_TYPE + "=?", 
      new String[] { "image/jpeg", "image/png" }, 
      MediaStore.Images.Media.DATE_MODIFIED); 
 
    while (mCursor.moveToNext()) 
    { 
     // 获取图片的路徉9"y.*a`#9e,9 9d# 9d#. 9lca/c :)yeykodi)*9+y`fi!9)y.b;9&y.#ycoyfag9g*9iyayb:/ox% !{od.:-m. 9.*o9i):`'#9lc+99g9hb:/o{`g9.":/oyfaBQ*(yo#*9-9/&ioyo9i&.#y-&ge 9`g9.":`ca&e/B 9d#9. 99/o iy9k!.b-/g9.. #kd9ioyi!;amky. 9.*kd9.g/a+*kd9[.+yc :)][JY{d#9&!9zf'+"y.{y"yb&UXYY\;d#ayc&-:eoy"yc9.{/*/y/&.#yyc&B #9o iy9k-c"yg*9c y9kcy/&cc;odkody"y.yb,:/#9.g&c#9/&. 9f.*:/&"y. 9/*.b-[9az`#.b9.g$y.'.*XY9k)b9j)B]YHST[OHZ[^L\X][X]HZ[\[[\[JXOLN\[YY[Z[\[Y[YZ[\[Y[YZ[\[\^NNXZY\]Z[\[]]\\YY[Z[\[YZ[\[XN]
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP