さてさて。久しぶりに会社絡み抜きでandroidアプリを作成しているのですが、もうひと踏ん張りで終了しそうです。
というわけで、今回はリファクタリングに焦点を当てます
環境
- android:minSdkVersion="14"
- android:targetSdkVersion="19"
volleyを利用したListViewの画像取得をキャッシュする
volleyはここ半年くらいで利用し始めました。とっても便利なライブラリです。デフォルトでも十分な性能ですが、チューニングするとさらにすばらしいことに!
リファクタリング前
よくありがちなVolleyを使ったListView処理です。
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
row = inflater.inflate(R.layout.fragment_user_row, parent, false);
}
UserPojo userPojo = mViewList.get(position);
ImageView userImage = (ImageView) row.findViewById(R.id.user_image);
ImageLoader.ImageListener userImageListener = ImageLoader.getImageListener(userImage, R.drawable.image_loading, R.drawable.no_image);
userImage.setTag(mImageLoader.get(userPojo.user_image_path, userImageListener));
TextView userName = (TextView) row.findViewById(R.id.user_name);
userName.setText(userPojo.user_name);
TextView startTime = (TextView) row.findViewById(R.id.start_time);
startTime.setText(userPojo.clime_start_time);
userPojo = null;
return row;
}
上記をViewHolderパターンとCancelRequestパターンを実装して書き換えます。
リファクタリング後
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
convertView = inflater.inflate(R.layout.fragment_user_row, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
View row = convertView;
if (row == null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
row = inflater.inflate(R.layout.fragment_user_row, parent, false);
}
// リクエストのキャンセル処理
ImageLoader.ImageContainer imageContainer = (ImageLoader.ImageContainer)holder.userImage.getTag();
if (imageContainer != null) {
imageContainer.cancelRequest();
}
UserPojo userPojo = mViewList.get(position);
ImageView userImage = (ImageView) row.findViewById(R.id.user_image);
ImageLoader.ImageListener userImageListener = ImageLoader.getImageListener(userImage, R.drawable.image_loading, R.drawable.no_image);
userImage.setTag(mImageLoader.get(userPojo.user_image_path, userImageListener));
holder.userName.setText(userPojo.user_name);
holder.startTime.setText(userPojo.start_time);
return convertView;
}
/**
* View holder pattern
*/
private class ViewHolder {
ImageView userImage;
TextView userName;
TextView startTime;
public ViewHolder(View view) {
this.userImage = (ImageView) view.findViewById(R.id.user_image);
this.userName = (TextView) view.findViewById(R.id.user_name);
this.startTime = (TextView) view.findViewById(R.id.start_time);
}
}
リストの一行のviewをViewHolderクラスを作ってキャッシュし、Viewの再利用時にImageViewからImageContainerのインスタンスを取得し、リクエストのキャンセルを行っています。
リファクタリング前と比較すると相当軽く、速くなります。
p.s 2014年8月までならこれでリファクタリング終了ですが、android Lが使えるようになると、RecyclerViewを使ってさらに高速化できるようです。これは正式版がリリースされたら説明したいと思います。
参考サイト
0 件のコメント:
コメントを投稿