閱讀104 返回首頁    go 阿裏雲 go 技術社區[雲棲]


提高顯示布局文件的性能 4 - 提升ListView的性能

Making ListView Scrolling Smooth [使得ListView滾動平滑]

使得滾動ListView平滑的關鍵在與保持AP的UI thread與複雜的操作隔離。
確保另起一個Thread來處理Disk IO,network access或者SQL access.
為了測試AP的狀態,可以enable StrictMode.(Android ICS 4.0上已經默認開啟了StrickMode)

Use a Background Thread [使用後台線程]

使用後台線程,這樣可以使得UI線程可以專注於描繪UI。
大多數時候,AsycnTask實現了一種簡單把需要做的事情與main thread隔離的方法。
[關於如何使用AsyncTask,請參考官方詳解,或者參看本人前麵一篇文章:使用AsyncTask來處理一些簡單的需要後台處理的動作]
下麵是一個例子:
  1. // Using an AsyncTask to load the slow images in a background thread  
  2. new AsyncTask<ViewHolder, Void, Bitmap>() {  
  3.     private ViewHolder v;  
  4.   
  5.     @Override  
  6.     protected Bitmap doInBackground(ViewHolder... params) {  
  7.         v = params[0];  
  8.         return mFakeImageLoader.getImage();  
  9.     }  
  10.   
  11.     @Override  
  12.     protected void onPostExecute(Bitmap result) {  
  13.         super.onPostExecute(result);  
  14.         if (v.position == position) {  
  15.             // If this item hasn't been recycled already, hide the  
  16.             // progress and set and show the image  
  17.             v.progress.setVisibility(View.GONE);  
  18.             v.icon.setVisibility(View.VISIBLE);  
  19.             v.icon.setImageBitmap(result);  
  20.         }  
  21.     }  
  22. }.execute(holder);  

從Android 3.0開始,對於AsyncTask有個額外的特色:在多核處理器的情況下,我們可以使用executeOnExecutor() 來替代execute(),這樣係統會根據當前設備的內核數量同時進行多個任務。

Hold View Objects in a View Holder [如何使用View Holder來Hold住view對象]

你的程序在滾動ListView的時候也許會重複頻繁的call findViewById(),這樣會降低性能。
盡管Adapter會因為循環機製返回一個創建好的View(關於這個機製,請參考鄙人前麵的文章:ListView中getView的原理與解決多輪重複調用的方法)
你仍然需要查找到這些組件並更新它,避免這樣的重複,我們可以使用ViewHolder的設計模式。

A ViewHolder對象存放每一個View組件於Layout的tag屬性中,因此我們可以立即訪問tag中的組件從而避免重複call findViewById()。

下麵是定義了一個ViewHolder的例子:
  1. static class ViewHolder {  
  2.   TextView text;  
  3.   TextView timestamp;  
  4.   ImageView icon;  
  5.   ProgressBar progress;  
  6.   int position;  
  7. }  
這樣之後,我們可以填充這個ViewHolder,並且保存到tag field.
  1. ViewHolder holder = new ViewHolder();  
  2. holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);  
  3. holder.text = (TextView) convertView.findViewById(R.id.listitem_text);  
  4. holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);  
  5. holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);  
  6. convertView.setTag(holder);  
那麼我們就可以直接訪問裏麵的數據了,省去了重複查詢,提升了性能。

最後更新:2017-04-04 07:03:07

  上一篇:go ASP.NET使用數據庫實現網站統計器
  下一篇:go 中國互聯網的恥辱