|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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上传功能...
敬请期待...
|
|