Universal Image Loader for Androidを使ってみた
参考: 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も揃ってる模様なので、用途としては非常に良いのは無いかと