如何为gridview重置适配器?

时间:2014-05-13 10:25:24

标签: java android gridview

我正在开发一个Android应用程序,它从服务器下载图像并将其显示在GridView上。为此,我使用了扩展BaseAdapter的适配器,其中我使用AsyncTask来获取图像并在gridview中显示ti。代码如下。

public class CloudImageAdapter extends BaseAdapter {
private final String TAG = "CloudImageAdapter";

private Context context;
private ThumbnailCache mCache;
private LayoutInflater inflater;

private ArrayList<String> images = new ArrayList<String>();
ServerInfo server = null;

public CloudImageAdapter(Context context) {
    this.context = context;

    inflater = (LayoutInflater) this.context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // Pick cache size based on memory class of device
    final ActivityManager am = (ActivityManager) this.context
            .getSystemService(Context.ACTIVITY_SERVICE);
    final int memoryClassBytes = am.getMemoryClass() * 1024 * 1024;
    mCache = new ThumbnailCache(memoryClassBytes / 2);
    server = ServerInfo.getServerInstance(context);

}

public void putImages(String imageName) {
    images.add(imageName);
}

@Override
public int getCount() {
    return images.size();
}

@Override
public Object getItem(int posotion) {
    Log.i(TAG, "getItem() returns -> " + images.get(posotion));
    return images.get(posotion);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View converView, ViewGroup parent) {
    ImageView imageView;
    if (converView == null) {
        converView = inflater.inflate(R.layout.single_image_frame, null);
        imageView = (ImageView) converView
                .findViewById(R.id.singleImageFrame);
        imageView.setImageBitmap(null);
        imageView.setBackgroundResource(R.drawable.empty_photo);
    } else {
        imageView = (ImageView) converView;
    }
    final AsyncImageDecoder oldTask = (AsyncImageDecoder) imageView
            .getTag();
    if (oldTask != null) {
        oldTask.cancel(false);
    }

    Bitmap bitmap = mCache.get(images.get(position));
    if (bitmap == null) {
        AsyncImageDecoder task = new AsyncImageDecoder(imageView);
        task.execute(images.get(position));
        imageView.setTag(task);
    }
    imageView.setImageBitmap(bitmap);
    return converView;
}

class Holder {
    ImageView frame;
}

/**
 * Simple extension that uses {@link Bitmap} instances as keys, using their
 * memory footprint in bytes for sizing.
 */
public static class ThumbnailCache extends
        android.support.v4.util.LruCache<String, Bitmap> {
    public ThumbnailCache(int maxSizeBytes) {
        super(maxSizeBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap data) {
        return data.getByteCount();
    }
}

class AsyncImageDecoder extends AsyncTask<String, Void, Bitmap> {
    private String END = "End-Of-File";
    private final WeakReference<ImageView> imageViewReference;
    float rotation = 0;

    public AsyncImageDecoder(ImageView frame) {
        imageViewReference = new WeakReference<ImageView>(frame);
    }

    @Override
    protected Bitmap doInBackground(String... imageName) {
        Log.i(TAG, "AsyncImageDecoder::doInBackground() image -> "
                + imageName[0]);
        Bitmap bitmap;
        try {
            bitmap = downloadImage(imageName[0]);
            mCache.put(String.valueOf(imageName[0]), bitmap);
            // rotation = getCameraPhotoOrientation(imagePath);
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Bitmap image) {
        if (imageViewReference != null && image != null) {
            final ImageView imageView = (ImageView) imageViewReference
                    .get();
            if (imageView != null) {
                /*
                 * if(image.getHeight() < image.getWidth())
                 * imageView.setRotation(90);
                 */
                imageView.setImageBitmap(image);
            }
        }
    }

    private Bitmap downloadImage(String path) throws IOException {

        Bitmap thumb = null;
        Socket socket = new Socket();
        socket.connect(server.getServerAddress());
        DataOutputStream out = new DataOutputStream(
                socket.getOutputStream());
        DataInputStream input = new DataInputStream(socket.getInputStream());

        JSONObject header = new JSONObject();
        JSONObject inner = new JSONObject();
        try {
            inner.put("command", "thumbnail");
            inner.put("user", server.getUser());
            inner.put("path", path);
            header.put("header", inner);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        out.write(header.toString().getBytes());
        out.write(END.getBytes());

        /*
         * Reading thumbnails from the cloud
         */
        byte[] temp = new byte[1024]; // Temporary byte array to read from
                                        // the socket
        byte[] store = null; // Reference variable to keep the byte array
        int len = 0; // Length of the array
        int receivedCount = 0;
        while (true) {
            receivedCount = input.read(temp);
            if (receivedCount <= 0) {
                thumb = decodeSampledBitmapFromUri(store, 50, 50);
                /*
                 * thumb = BitmapFactory.decodeByteArray(store, 0,
                 * store.length);
                 */
                break; // Break when there is no more data to be read
            }
            byte[] buffer = new byte[len + receivedCount];
            if (store != null) {
                System.arraycopy(store, 0, buffer, 0, store.length);
                System.arraycopy(temp, 0, buffer, len, receivedCount);
            } else {
                System.arraycopy(temp, 0, buffer, 0, receivedCount);
            }
            store = buffer;
            len = len + receivedCount;
        }
        input.close();
        out.close();
        socket.close();

        return thumb;
    }

    private Bitmap decodeSampledBitmapFromUri(byte[] data, int width,
            int height) {
        Bitmap bm = null;
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(data, 0, data.length, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, 140, 120);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        bm = BitmapFactory.decodeByteArray(data, 0, data.length, options);
        return bm;

    }

    private 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) {
            if (width > height) {
                inSampleSize = Math.round((float) height
                        / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
            }
        }
        return inSampleSize;
    }

}}

问题是当我在选项卡上运行此代码时,会下载大约30个图像。当我离开活动(没有完全加载图像)到任何其他活动时,应用程序等待,直到图像下载完成。当应用程序退出时,有没有办法立即停止所有AsyncTask

2 个答案:

答案 0 :(得分:0)

AsyncTask的while循环内部,如果我们离开活动,请包含以下代码以提前退出循环:

if (isCancelled()) 
    break;

然后使用

task.cancel(true);

在您活动的AsyncTask事件中的onPause()对象上,这会将isCancelled()设置为true,并且会在您离开活动时暂停下载图片。

答案 1 :(得分:0)

您要做的是在Activity在后​​台时暂停任务。下面的代码将暂停功能添加到AsyncTask

class AsyncImageDecoder extends AsyncTask<String, Void, Bitmap> {
private String END = "End-Of-File";
private final WeakReference<ImageView> imageViewReference;
float rotation = 0;

boolean resume = true;
boolean pause = false;
private String WATCH_DOG = "griffin";

public AsyncImageDecoder(ImageView frame) {
    imageViewReference = new WeakReference<ImageView>(frame);
}

@Override
protected Bitmap doInBackground(String... imageName) {
    Log.i(TAG, "AsyncImageDecoder::doInBackground() image -> "
            + imageName[0]);
    Bitmap bitmap;
    while(resume){
        try {
            bitmap = downloadImage(imageName[0]);
            mCache.put(String.valueOf(imageName[0]), bitmap);
            // rotation = getCameraPhotoOrientation(imagePath);
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(pause){ //This checks if the task has been paused and sleeps it till it has been notified to wake up
            syncronized(WATCH_DOG){
                try{
                    WATCH_DOG.wait();
                } catch (InterruptedException e){e.printStackTrace();}
                pause = false;
            }
        }
    }
    return null;
}

public void pauseTask(){
    pause = true;
}

public void wakeUp(){
    synchronized(WATCH_DOG){
        WATCH_DOG.notify();
    }
}

@Override
protected void onPostExecute(Bitmap image) {
    if (imageViewReference != null && image != null) {
        final ImageView imageView = (ImageView) imageViewReference
                .get();
        if (imageView != null) {
            /*
             * if(image.getHeight() < image.getWidth())
             * imageView.setRotation(90);
             */
            imageView.setImageBitmap(image);
        }
    }
}

private Bitmap downloadImage(String path) throws IOException {

    Bitmap thumb = null;
    Socket socket = new Socket();
    socket.connect(server.getServerAddress());
    DataOutputStream out = new DataOutputStream(
            socket.getOutputStream());
    DataInputStream input = new DataInputStream(socket.getInputStream());

    JSONObject header = new JSONObject();
    JSONObject inner = new JSONObject();
    try {
        inner.put("command", "thumbnail");
        inner.put("user", server.getUser());
        inner.put("path", path);
        header.put("header", inner);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    out.write(header.toString().getBytes());
    out.write(END.getBytes());

    /*
     * Reading thumbnails from the cloud
     */
    byte[] temp = new byte[1024]; // Temporary byte array to read from
                                    // the socket
    byte[] store = null; // Reference variable to keep the byte array
    int len = 0; // Length of the array
    int receivedCount = 0;
    while (true) {
        receivedCount = input.read(temp);
        if (receivedCount <= 0) {
            thumb = decodeSampledBitmapFromUri(store, 50, 50);
            /*
             * thumb = BitmapFactory.decodeByteArray(store, 0,
             * store.length);
             */
            break; // Break when there is no more data to be read
        }
        byte[] buffer = new byte[len + receivedCount];
        if (store != null) {
            System.arraycopy(store, 0, buffer, 0, store.length);
            System.arraycopy(temp, 0, buffer, len, receivedCount);
        } else {
            System.arraycopy(temp, 0, buffer, 0, receivedCount);
        }
        store = buffer;
        len = len + receivedCount;
    }
    input.close();
    out.close();
    socket.close();

    return thumb;
}

private Bitmap decodeSampledBitmapFromUri(byte[] data, int width,
        int height) {
    Bitmap bm = null;
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeByteArray(data, 0, data.length, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, 140, 120);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    bm = BitmapFactory.decodeByteArray(data, 0, data.length, options);
    return bm;

}

private 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) {
        if (width > height) {
            inSampleSize = Math.round((float) height
                    / (float) reqHeight);
        } else {
            inSampleSize = Math.round((float) width / (float) reqWidth);
        }
    }
    return inSampleSize;
}

}}

在此之后,您需要在Activity处于后台时添加更改,例如:

@Override
public void onPause(){
    super.onPause();
    task.pauseTask();
}

@Override
public void onResume(){
    super.onResume();
    task.wakeUp();
}

这应该意味着你离开它时不必完全破坏任务,当你回到它时它应该继续。