Android性能最適化のListView性能向上テクニック
8126 ワード
ListViewの最適化は常に一般的な問題であり、面接でも通常の開発でもListViewは無視されません.では、この文章では、ListViewのパフォーマンスを最大化する方法を見てみましょう. 1.adapterのgetViewメソッドでは、論理 をできるだけ少なく使用します. 2.GC はできるだけ避ける 3.スライド時に画像 をロードしない 4.ListViewのscrollingCacheとanimateCacheをfalse に設定 5.itemのレイアウトレベルは、焼くほど になります. 6.ViewHolder の使用
1.adapterでのgetViewメソッドでは論理の使用を最小限に抑える
getView()に論理コードを書きすぎないでください.たとえば、次のような場所に置くことができます.
最適化前のgetView():
最適化されたgetView():
2.GCゴミ回収器
大量のオブジェクトを作成するとGCは頻繁に実行されるのでgetView()メソッドでは多くのオブジェクトを作成しないでください.最も最適化されているのは、ViewHolder以外のオブジェクトを作成しないでください.もしあなたのロゴに「GC has freed some memory」が頻繁に現れていることを発見したら、あなたのプログラムに問題があるに違いありません.a)itemレイアウトの階層が深すぎるかどうかを確認できますb)getView()メソッドにc)ListViewのレイアウトプロパティが多数存在するかどうかを確認できます.
3.画像のロード
もしあなたのListViewにネットからダウンロードした画像を表示する必要があるならば、私達はListViewがスライドする時に画像をロードしないでください、それではListViewがカートンになることができて、だから私達は更にリスナーの中でListViewの状態を傍受する必要があって、もしスライドする時、画像を追加することを停止して、もしスライドしていないならば、画像をロードし始めます
4.ListViewのscrollingCacheとanimateCacheをfalseに設定
scrollingCache:scrollingCacheは本質的にdrawing cacheです.ビューに自分のdrawingをcacheに保存させることができます(bitmapとして保存されます).そうすれば、次回ビューを表示するときに再描画するのではなく、cacheから取り出すことができます.デフォルトではdrawing cahceは無効です.メモリが消費されるためですが、絵よりもスムーズに描かれています.ListViewではscrollingCacheがデフォルトでオンになっており、手動でオフにすることができます.
animateCache:ListViewではデフォルトでanimateCacheがオンになっています.これによりメモリが大量に消費されるため、頻繁にGCが呼び出され、手動で閉じることができます.
最適化前のListView
最適化されたListView
5.itemのレイアウトの深さを減らす
ListViewをスライドさせると、測定と描画が直接発生するため、itemレイアウトの深さを最小限に抑える必要があります.そのため、不要なレイアウトネスト関係を削除する必要があります.itemレイアウトの深さを減らす
6.ViewHolderの使用
これはよく知っているはずですが、このViewHolderを軽視しないでください.ListViewのパフォーマンスを大幅に向上させることができます.
ListViewの最適化はもう終わりました.もしあなたのプロジェクトの中で、これらの基本的な最適化がまだできていないならば、あなたのListViewは問題があって、まだ大きな向上潜在力があります.後でListViewを使うときは、必ずこれらの点を考慮して、その最大の性能を発揮しなければなりません.
1.adapterでのgetViewメソッドでは論理の使用を最小限に抑える
getView()に論理コードを書きすぎないでください.たとえば、次のような場所に置くことができます.
最適化前のgetView():
@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
Object current_event = mObjects.get(position);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_event, null);
holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// ,
if (doesSomeComplexChecking()) {
holder.ThreeDimention.setVisibility(View.VISIBLE);
} else {
holder.ThreeDimention.setVisibility(View.GONE);
}
// image , getView ,
RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
holder.EventPoster.setLayoutParams(imageParams);
return convertView;
}
最適化されたgetView():
@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
Object object = mObjects.get(position);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_event, null);
holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
// , ,
RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
holder.EventPoster.setLayoutParams(imageParams);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// getter ,
holder.ThreeDimension.setVisibility(object.getVisibility());
return convertView;
}
2.GCゴミ回収器
大量のオブジェクトを作成するとGCは頻繁に実行されるのでgetView()メソッドでは多くのオブジェクトを作成しないでください.最も最適化されているのは、ViewHolder以外のオブジェクトを作成しないでください.もしあなたのロゴに「GC has freed some memory」が頻繁に現れていることを発見したら、あなたのプログラムに問題があるに違いありません.a)itemレイアウトの階層が深すぎるかどうかを確認できますb)getView()メソッドにc)ListViewのレイアウトプロパティが多数存在するかどうかを確認できます.
3.画像のロード
もしあなたのListViewにネットからダウンロードした画像を表示する必要があるならば、私達はListViewがスライドする時に画像をロードしないでください、それではListViewがカートンになることができて、だから私達は更にリスナーの中でListViewの状態を傍受する必要があって、もしスライドする時、画像を追加することを停止して、もしスライドしていないならば、画像をロードし始めます
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView listView, int scrollState) {
//
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
imageLoader.stopProcessingQueue();
} else {
//
imageLoader.startProcessingQueue();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
4.ListViewのscrollingCacheとanimateCacheをfalseに設定
scrollingCache:scrollingCacheは本質的にdrawing cacheです.ビューに自分のdrawingをcacheに保存させることができます(bitmapとして保存されます).そうすれば、次回ビューを表示するときに再描画するのではなく、cacheから取り出すことができます.デフォルトではdrawing cahceは無効です.メモリが消費されるためですが、絵よりもスムーズに描かれています.ListViewではscrollingCacheがデフォルトでオンになっており、手動でオフにすることができます.
animateCache:ListViewではデフォルトでanimateCacheがオンになっています.これによりメモリが大量に消費されるため、頻繁にGCが呼び出され、手動で閉じることができます.
最適化前のListView
"@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#00000000"
android:divider="@color/list_background_color"
android:dividerHeight="0dp"
android:listSelector="#00000000"
android:smoothScrollbar="true"
android:visibility="gone" />
最適化されたListView
"@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/list_background_color"
android:dividerHeight="0dp"
android:listSelector="#00000000"
android:scrollingCache="false"
android:animationCache="false"
android:smoothScrollbar="true"
android:visibility="gone" />
5.itemのレイアウトの深さを減らす
ListViewをスライドさせると、測定と描画が直接発生するため、itemレイアウトの深さを最小限に抑える必要があります.そのため、不要なレイアウトネスト関係を削除する必要があります.itemレイアウトの深さを減らす
6.ViewHolderの使用
これはよく知っているはずですが、このViewHolderを軽視しないでください.ListViewのパフォーマンスを大幅に向上させることができます.
ListViewの最適化はもう終わりました.もしあなたのプロジェクトの中で、これらの基本的な最適化がまだできていないならば、あなたのListViewは問題があって、まだ大きな向上潜在力があります.後でListViewを使うときは、必ずこれらの点を考慮して、その最大の性能を発揮しなければなりません.