Android Open Source - cube-sdk Image Task






From Project

Back to project page cube-sdk.

License

The source code is released under:

Apache License

If you think the Android project cube-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package in.srain.cube.image;
//from  w  w w  . j a  va2 s .  c  om
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import in.srain.cube.image.iface.ImageLoadHandler;
import in.srain.cube.util.CLog;
import in.srain.cube.util.Debug;
import in.srain.cube.util.Encrypt;

import java.lang.ref.WeakReference;

/**
 * A wrapper of the related information used in loading a bitmap
 *
 * @author http://www.liaohuqiu.net
 */
public class ImageTask {

    protected static final String LOG_TAG = Debug.DEBUG_IMAGE_LOG_TAG_TASK;
    private static final Object sPoolSync = new Object();
    private static ImageTask sTop;
    private static int sPoolSize = 0;
    private static final int MAX_POOL_SIZE = 20;
    private static boolean USE_POOL = false;

    private static int sId = 0;

    private final static String SIZE_SP = "_";
    private final static int STATUS_PRE_LOAD = 0x01;
    private final static int STATUS_LOADING = 0x02;
    private final static int STATUS_DONE = 0x04;
    private final static int STATUS_CANCELED = 0x08;
    private final static int STATUS_FAIL = 0x10;

    public final static int ERROR_NETWORK = 0x01;

    private int mFlag = 0;
    protected int mId = 0;

    // the origin request url for the image.
    protected String mOriginUrl;

    // In some situations, we may store the same image in some different servers. So the same image will related to some different urls.
    private String mIdentityUrl;

    // The key related to the image this ImageTask is requesting.
    private String mIdentityKey;

    // cache for toString();
    private String mStr;

    protected Point mRequestSize = new Point();
    protected Point mBitmapOriginSize = new Point();
    protected ImageReuseInfo mReuseInfo;

    protected ImageViewHolder mFirstImageViewHolder;
    protected ImageTaskStatistics mImageTaskStatistics;

    ImageTask next;

    protected void clearForRecycle() {
        mFlag = 0;

        mOriginUrl = null;
        mIdentityUrl = null;
        mIdentityKey = null;
        mStr = null;
        mRequestSize.set(0, 0);
        mBitmapOriginSize.set(0, 0);

        mReuseInfo = null;
        mFirstImageViewHolder = null;
        mImageTaskStatistics = null;
    }

    public static ImageTask obtain() {
        if (!USE_POOL) {
            return null;
        }
        // pop top, make top.next as top
        synchronized (sPoolSync) {
            if (sTop != null) {
                ImageTask m = sTop;
                sTop = m.next;
                m.next = null;
                sPoolSize--;
                return m;
            }
            if (Debug.DEBUG_IMAGE) {
                CLog.d(LOG_TAG, "obtain, pool remain: %d", sPoolSize);
            }
        }
        return null;
    }

    public void tryToRecycle() {
        if (!USE_POOL) {
            return;
        }
        clearForRecycle();

        // mark top as the next of current, then push current as pop
        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sTop;
                sTop = this;
                sPoolSize++;
            }
            if (Debug.DEBUG_IMAGE) {
                CLog.d(LOG_TAG, "recycle, pool remain: %d", sPoolSize);
            }
        }
    }

    public ImageTask renew() {
        mId = ++sId;
        if (ImagePerformanceStatistics.sample(mId)) {
            mImageTaskStatistics = new ImageTaskStatistics();
        }
        return this;
    }

    public ImageTask setOriginUrl(String originUrl) {
        mOriginUrl = originUrl;
        return this;
    }

    public ImageTask setRequestSize(int requestWidth, int requestHeight) {
        mRequestSize.set(requestWidth, requestHeight);
        return this;
    }

    public ImageTask setReuseInfo(ImageReuseInfo imageReuseInfo) {
        mReuseInfo = imageReuseInfo;
        return this;
    }

    /**
     * For accessing the identity url
     *
     * @return
     */
    public String getIdentityUrl() {
        if (null == mIdentityUrl) {
            mIdentityUrl = generateIdentityUrl(mOriginUrl);
        }
        return mIdentityUrl;
    }

    /**
     * In some situations, we may store the same image in some different servers. So the same image will related to some different urls.
     * <p/>
     * Generate the identity url according your situation.
     * <p/>
     * {@link #mIdentityUrl}
     *
     * @return
     */
    protected String generateIdentityUrl(String originUrl) {
        return originUrl;

    }

    /**
     * Generate the identity key.
     * <p/>
     * This key should be related to the unique image this task is requesting: the size, the remote url.
     *
     * @return
     */
    protected String generateIdentityKey() {
        if (mReuseInfo == null) {
            return joinSizeInfoToKey(getIdentityUrl(), mRequestSize.x, mRequestSize.y);
        } else {
            return joinSizeTagToKey(getIdentityUrl(), mReuseInfo.getIdentitySize());
        }
    }

    public boolean isPreLoad() {
        return (mFlag & STATUS_PRE_LOAD) == STATUS_PRE_LOAD;
    }

    public void setIsPreLoad() {
        mFlag = mFlag | STATUS_PRE_LOAD;
    }

    public boolean isLoading() {
        return (mFlag & STATUS_LOADING) != 0;
    }

    /**
     * Check the given url is loading.
     *
     * @param url
     * @return Identify the given url, if same to {@link #mIdentityUrl} return true.
     */
    public boolean isLoadingThisUrl(String url) {
        return getIdentityUrl().equals(generateIdentityUrl(url));
    }

    /**
     * Bind ImageView with ImageTask
     *
     * @param imageView
     */
    public void addImageView(CubeImageView imageView) {
        if (null == imageView) {
            return;
        }
        if (null == mFirstImageViewHolder) {
            mFirstImageViewHolder = new ImageViewHolder(imageView);
            return;
        }

        ImageViewHolder holder = mFirstImageViewHolder;
        for (; ; holder = holder.mNext) {
            if (holder.contains(imageView)) {
                return;
            }
            if (holder.mNext == null) {
                break;
            }
        }

        ImageViewHolder newHolder = new ImageViewHolder(imageView);
        newHolder.mPrev = holder;
        holder.mNext = newHolder;
    }

    /**
     * Remove the ImageView from ImageTask
     *
     * @param imageView
     */
    public void removeImageView(CubeImageView imageView) {

        if (null == imageView || null == mFirstImageViewHolder) {
            return;
        }

        ImageViewHolder holder = mFirstImageViewHolder;

        do {
            if (holder.contains(imageView)) {

                // Make sure entry is right.
                if (holder == mFirstImageViewHolder) {
                    mFirstImageViewHolder = holder.mNext;
                }
                if (null != holder.mNext) {
                    holder.mNext.mPrev = holder.mPrev;
                }
                if (null != holder.mPrev) {
                    holder.mPrev.mNext = holder.mNext;
                }
            }

        } while ((holder = holder.mNext) != null);
    }

    /**
     * Check if this ImageTask has any related ImageViews.
     *
     * @return
     */
    public boolean stillHasRelatedImageView() {
        if (null == mFirstImageViewHolder || mFirstImageViewHolder.getImageView() == null) {
            return false;
        } else {
            return true;
        }
    }

    public void onLoading(ImageLoadHandler handler) {
        mFlag = mFlag | STATUS_LOADING;

        if (null == handler) {
            return;
        }

        if (mFirstImageViewHolder == null) {
            handler.onLoading(this, null);
        } else {
            ImageViewHolder holder = mFirstImageViewHolder;
            do {
                final CubeImageView imageView = holder.getImageView();
                if (null != imageView) {
                    handler.onLoading(this, imageView);
                }
            } while ((holder = holder.mNext) != null);
        }
    }

    /**
     * Will be called when begin load image data from dish or network
     *
     * @param drawable
     */
    public void onLoadFinish(BitmapDrawable drawable, ImageLoadHandler handler) {

        mFlag &= ~STATUS_LOADING;
        mFlag |= STATUS_DONE;

        if (null == handler) {
            return;
        }

        if (null != mImageTaskStatistics) {
            mImageTaskStatistics.showBegin();
        }
        if (mFirstImageViewHolder == null) {
            handler.onLoadFinish(this, null, drawable);
        } else {
            ImageViewHolder holder = mFirstImageViewHolder;
            do {
                final CubeImageView imageView = holder.getImageView();
                if (null != imageView) {
                    imageView.onLoadFinish();
                    handler.onLoadFinish(this, imageView, drawable);
                }
            } while ((holder = holder.mNext) != null);
        }
        if (null != mImageTaskStatistics) {
            mImageTaskStatistics.showComplete(ImageProvider.getBitmapSize(drawable));
        }
    }

    public void onCancel() {
        mFlag &= ~STATUS_LOADING;
        mFlag |= STATUS_CANCELED;
    }

    public void onLoadError(int reason, ImageLoadHandler handler) {
        mFlag &= ~STATUS_LOADING;
        mFlag |= STATUS_FAIL;
        if (mFirstImageViewHolder == null) {
            handler.onLoadError(this, null, reason);
        } else {
            ImageViewHolder holder = mFirstImageViewHolder;
            do {
                final CubeImageView imageView = holder.getImageView();
                if (null != imageView) {
                    imageView.onLoadFinish();
                    handler.onLoadError(this, imageView, reason);
                }
            } while ((holder = holder.mNext) != null);

        }
    }

    /**
     * If you have a thumbnail web service which can return multiple size image according the url,
     * <p/>
     * you can implements this method to return the specified url according the request size.
     *
     * @return
     */
    public String getRemoteUrl() {
        return mOriginUrl;
    }

    /**
     * Return the origin request url
     *
     * @return
     */
    public String getOriginUrl() {
        return mOriginUrl;
    }

    public void setBitmapOriginSize(int width, int height) {
        mBitmapOriginSize.set(width, height);
    }

    public Point getBitmapOriginSize() {
        return mBitmapOriginSize;
    }

    public Point getRequestSize() {
        return mRequestSize;
    }

    /**
     * Return the key which identifies this Image Wrapper object.
     */
    public String getIdentityKey() {
        if (mIdentityKey == null) {
            mIdentityKey = generateIdentityKey();
        }
        return mIdentityKey;
    }

    /**
     * Join the key and the size information.
     *
     * @param key
     * @param w
     * @param h
     * @return "$key" + "_" + "$w" + "_" + "$h"
     */
    public static String joinSizeInfoToKey(String key, int w, int h) {
        if (w > 0 && h != Integer.MAX_VALUE && h > 0 && h != Integer.MAX_VALUE) {
            return new StringBuilder(key).append(SIZE_SP).append(w).append(SIZE_SP).append(h).toString();
        }
        return key;
    }

    /**
     * Join the tag with the key.
     *
     * @param key
     * @param tag
     * @return "$key" + "_" + "$tag"
     */
    public static String joinSizeTagToKey(String key, String tag) {
        return new StringBuilder(key).append(SIZE_SP).append(tag).toString();
    }

    /**
     * Return the cache key for file cache.
     *
     * @return the cache key for file cache.
     */
    public String getFileCacheKey() {
        return Encrypt.md5(getIdentityKey());
    }

    /**
     * @param sizeKey
     * @return
     */
    public String generateFileCacheKeyForReuse(String sizeKey) {
        return Encrypt.md5(joinSizeTagToKey(getIdentityUrl(), sizeKey));
    }

    public ImageReuseInfo getImageReuseInfo() {
        return mReuseInfo;
    }

    @Override
    public boolean equals(Object object) {
        if (object != null && object instanceof ImageTask) {
            return ((ImageTask) object).getIdentityKey().equals(getIdentityKey());
        }
        return false;
    }

    @Override
    public String toString() {
        if (mStr == null) {
            mStr = String.format("%s %sx%s", mId, mRequestSize.x, mRequestSize.y);
        }
        return mStr;
    }

    public ImageTaskStatistics getStatistics() {
        return mImageTaskStatistics;
    }

    /**
     * A tiny and light linked-list like container to hold all the ImageViews related to the ImageTask.
     */
    private static class ImageViewHolder {
        private WeakReference<CubeImageView> mImageViewRef;
        private ImageViewHolder mNext;
        private ImageViewHolder mPrev;

        public ImageViewHolder(CubeImageView imageView) {
            mImageViewRef = new WeakReference<CubeImageView>(imageView);
        }

        boolean contains(CubeImageView imageView) {
            return mImageViewRef != null && imageView == mImageViewRef.get();
        }

        CubeImageView getImageView() {
            if (null == mImageViewRef) {
                return null;
            }
            return mImageViewRef.get();
        }
    }
}




Java Source Code List

in.srain.cube.Cube.java
in.srain.cube.app.CubeFragmentActivity.java
in.srain.cube.app.CubeFragment.java
in.srain.cube.app.FragmentParam.java
in.srain.cube.app.ICubeFragment.java
in.srain.cube.app.XActivity.java
in.srain.cube.app.lifecycle.IComponentContainer.java
in.srain.cube.app.lifecycle.LifeCycleComponentManager.java
in.srain.cube.app.lifecycle.LifeCycleComponent.java
in.srain.cube.cache.CacheInfo.java
in.srain.cube.cache.CacheManager.java
in.srain.cube.cache.CacheResultType.java
in.srain.cube.cache.ICacheAble.java
in.srain.cube.cache.IFileCache.java
in.srain.cube.cache.QueryHandler.java
in.srain.cube.cache.Query.java
in.srain.cube.concurrent.BlockingDeque.java
in.srain.cube.concurrent.Deque.java
in.srain.cube.concurrent.LinkedBlockingDeque.java
in.srain.cube.concurrent.SimpleExecutor.java
in.srain.cube.concurrent.SimpleTask.java
in.srain.cube.file.DiskLruCache.java
in.srain.cube.file.FileUtil.java
in.srain.cube.file.LruFileCache.java
in.srain.cube.image.CubeImageView.java
in.srain.cube.image.ImageLoaderFactory.java
in.srain.cube.image.ImageLoader.java
in.srain.cube.image.ImagePerformanceStatistics.java
in.srain.cube.image.ImageProvider.java
in.srain.cube.image.ImageReuseInfoManger.java
in.srain.cube.image.ImageReuseInfo.java
in.srain.cube.image.ImageTaskStatistics.java
in.srain.cube.image.ImageTask.java
in.srain.cube.image.drawable.RecyclingBitmapDrawable.java
in.srain.cube.image.drawable.RoundedDrawable.java
in.srain.cube.image.iface.ImageFileProvider.java
in.srain.cube.image.iface.ImageLoadHandler.java
in.srain.cube.image.iface.ImageLoadProgressHandler.java
in.srain.cube.image.iface.ImageMemoryCache.java
in.srain.cube.image.iface.ImageResizer.java
in.srain.cube.image.iface.ImageTaskExecutor.java
in.srain.cube.image.impl.DefaultImageLoadHandler.java
in.srain.cube.image.impl.DefaultImageResizer.java
in.srain.cube.image.impl.DefaultImageTaskExecutor.java
in.srain.cube.image.impl.DefaultMemoryCache.java
in.srain.cube.image.impl.LruImageFileProvider.java
in.srain.cube.image.impl.SimpleDownloader.java
in.srain.cube.mints.base.BlockMenuFragment.java
in.srain.cube.mints.base.DemoBaseActivity.java
in.srain.cube.mints.base.TitleBaseActivity.java
in.srain.cube.mints.base.TitleBaseFragment.java
in.srain.cube.mints.base.TitleHeaderBar.java
in.srain.cube.request.CacheAbleRequestDefaultHandler.java
in.srain.cube.request.CacheAbleRequestHandler.java
in.srain.cube.request.CacheAbleRequestJsonHandler.java
in.srain.cube.request.CacheAbleRequest.java
in.srain.cube.request.FailData.java
in.srain.cube.request.ICacheAbleRequest.java
in.srain.cube.request.IRequest.java
in.srain.cube.request.JsonData.java
in.srain.cube.request.RequestBase.java
in.srain.cube.request.RequestCacheManager.java
in.srain.cube.request.RequestData.java
in.srain.cube.request.RequestDefaultHandler.java
in.srain.cube.request.RequestFinishHandler.java
in.srain.cube.request.RequestHandler.java
in.srain.cube.request.RequestJsonHandler.java
in.srain.cube.request.SimpleJsonRequest.java
in.srain.cube.request.SimpleRequestManager.java
in.srain.cube.request.SimpleRequest.java
in.srain.cube.uri.CustomizedUri.java
in.srain.cube.util.Debug.java
in.srain.cube.util.Encrypt.java
in.srain.cube.util.Env.java
in.srain.cube.util.LocalDisplay.java
in.srain.cube.util.NetworkStatusManager.java
in.srain.cube.util.ResourceMan.java
in.srain.cube.util.SystemWatcher.java
in.srain.cube.util.Version.java
in.srain.cube.views.DotView.java
in.srain.cube.views.IScrollHeaderFrameHandler.java
in.srain.cube.views.MoreActionView.java
in.srain.cube.views.ScrollHeaderFrame.java
in.srain.cube.views.banner.BannerAdapter.java
in.srain.cube.views.banner.PagerIndicator.java
in.srain.cube.views.banner.SliderBanner.java
in.srain.cube.views.block.BlockListAdapter.java
in.srain.cube.views.block.BlockListView.java
in.srain.cube.views.list.ListPageInfo.java
in.srain.cube.views.list.ListViewDataAdapterBase.java
in.srain.cube.views.list.ListViewDataAdapter.java
in.srain.cube.views.list.PagedListDataModel.java
in.srain.cube.views.list.PagedListViewDataAdapter.java
in.srain.cube.views.list.ViewHolderBase.java
in.srain.cube.views.list.ViewHolderCreator.java
in.srain.cube.views.mix.AutoPlayer.java
in.srain.cube.views.pager.PageIndicator.java
in.srain.cube.views.pager.TabPageIndicator.java