Universal Image Loader for Androidを使ってみた

2013-05-10T00:00:00+00:00 Android Java

参考: http://qiita.com/chuross/items/e3ca79065d9b67716ace

https://github.com/nostra13/Android-Universal-Image-Loader

ちょうど、AndroidAnnotations+Twitter4jで作ってたデモアプリ的なのがあったので、そいつでプロフィール画像をロードする仕組みな所をこのUniversal Image Loaderを使ってプロフィール画像を読み込むっていうのを処理してみた

インストール

JARが提供されているし、maven repositoriesにもある模様。とりまぁいつもどおりgithubからcloneした後にそいつをライブラリプロジェクトとしてEclipseでインポート。で使うプロジェクトで参照追加的な感じで

あと、Universal Image LoaderのStorageUtilsっていうクラスで画像のキャッシュディレクトリとかを操作するにあたってSDカードにキャッシュする場合にはWRITE_EXTERNAL_STORAGEなパーミッションが必要なので使うプロジェクトで設定しておく

MainActivity.java

Universal Image Loaderの初期化辺りとかを行う。Universal Image Loader公式なサンプルではandroid.app.Applicationを継承したクラスを作ってそこで初期化処理している

package kinjouj.aatwitter;

import java.io.File;

import android.app.ListActivity;
import android.util.Log;

import com.googlecode.androidannotations.annotations.AfterInject;
import com.googlecode.androidannotations.annotations.AfterViews;
import com.googlecode.androidannotations.annotations.Bean;
import com.googlecode.androidannotations.annotations.EActivity;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.utils.StorageUtils;

import twitter4j.Twitter;
import twitter4j.TwitterException;

@EActivity(R.layout.main)
public class MainActivity extends ListActivity {

    private static final String TAG = MainActivity.class.getName();

    @Bean
    protected Token token;

    private Twitter twitter;

    @AfterInject
    public void init() {
        Log.v(TAG, "init");

        twitter = token.getTwitter();
    }

    @AfterViews
    public void initViews() {
        Log.v(TAG, "initViews");

        File cacheDir = StorageUtils.getCacheDirectory(this);

        DisplayImageOptions options = new DisplayImageOptions.Builder()
            .cacheOnDisc()
            .build();

        ImageLoader.getInstance().init(
            new ImageLoaderConfiguration.Builder(this)
                .discCache(new UnlimitedDiscCache(cacheDir))
                .defaultDisplayImageOptions(options)
                .build()
        );

        try {
            AAAdapter adapter = new AAAdapter(
                getApplicationContext(),
                twitter.getHomeTimeline()
            );

            setListAdapter(adapter);
        } catch (TwitterException e) {
            e.printStackTrace();
        }
    }
}

DisplayImageOptions的なのはImageLoaderのメソッドの引数でも指定出来る。ImageLoaderを使うには一度initを実行しなければならないらしいので(例外が出る)

AAAdapter.java

package kinjouj.aatwitter;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;

import twitter4j.ResponseList;
import twitter4j.Status;

public class AAAdapter extends BaseAdapter {

    private static final String TAG = AAAdapter.class.getName();

    private Context context;
    private ResponseList<Status> statuses;

    public AAAdapter(Context context, ResponseList<Status> statuses) {
        this.context = context;
        this.statuses = statuses;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.v(TAG, "getView");

        View view = convertView;

        if (view == null) {
            LayoutInflater inflater = LayoutInflater.from(context);
            view = (RelativeLayout)inflater.inflate(R.layout.tweet, null);
        }

        final RelativeLayout layout = (RelativeLayout)view;

        Status status = (Status)getItem(position);

        TextView tweetText = (TextView)layout.findViewById(R.id.tweetText);
        tweetText.setText(status.getText());

        ImageLoader imageLoader = ImageLoader.getInstance();

        imageLoader.loadImage(
            status.getUser().getProfileImageURLHttps(),
            new SimpleImageLoadingListener() {
                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                    ImageView imageView = (ImageView)layout.findViewById(R.id.userIcon);

                    imageView.setImageBitmap(
                        Bitmap.createScaledBitmap(loadedImage, 100, 100, true)
                    );
                }
            }
        );

        return view;
    }

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

    @Override
    public Object getItem(int position) {
        return statuses.get(position);
    }

    @Override
    public long getItemId(int position) {
        Status status = (Status)getItem(position);

        return status.getId();
    }
}

ImageLoader.loadImageメソッドを使って、指定したURLの画像を取得。んでロードできたらImageViewに一度createScaledBitmapを介してから設定等。displayImageっていうメソッドを使う事で引数にImageViewとかを指定しても出来るんだけど、リサイズ的な方法がちょいと不明だったので、loadImageを使って自分でバインドする也でやってみた所

まぁこんだけ。他にもキャッシュ数を制限できたりとかも出来るし、LRU方式なメモリキャッシュ機構なAPIも揃ってる模様なので、用途としては非常に良いのは無いかと

Android SlidingMenuを試す 「VirtualBox VMs」のディレクトリがウザい件