Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> [Android]ListView性能優化之視圖緩存(續)

[Android]ListView性能優化之視圖緩存(續)

編輯:Android開發實例

前言

  在上一篇ListView性能優化之視圖緩存我們討論了Google I/O中的優化方法,在各個論壇發帖後得到了不錯的反饋,諸如:使用ViewHolder技術Tag的問題,利用HashMap自行存儲的方案等。這裡結合新浪微博中主界面的做法及測試數據與大家進一步探討。
 

  

文章

  [Android]ListView性能優化之視圖緩存 [本文的上篇]
 

  [Android]ListView性能優化之視圖緩存 [JavaEye討論帖]
 

 

正文

  一、新浪微博

    1.1  截圖

      (來自網絡)

    1.2  反編譯後相關代碼

      HomeListActivity

    public View getView(int paramInt, View paramView, ViewGroup paramViewGroup)
    {
      int i = --paramInt;
      int j = -1;
      if (i == j);
      for (Object localObject1 = HomeListActivity.this.getReloadView(); ; localObject1 = HomeListActivity.this.getLoadMoreView())
      {
        label26: return localObject1;
        int k = HomeListActivity.this.mList.size();
        int l = paramInt;
        int i1 = k;
        if (l != i1)
          break;
      }
      boolean bool1 = true;
      boolean bool2 = null;
      String str1;
      label110: Object localObject2;
      if (StaticInfo.mUser == null)
      {
        List localList1 = HomeListActivity.this.mList;
        int i2 = paramInt;
        str1 = ((MBlog)localList1.get(i2)).uid;
        List localList2 = HomeListActivity.this.mList;
        int i3 = paramInt;
        String str2 = ((MBlog)localList2.get(i3)).uid;
        String str3 = str1;
        if (!str2.equals(str3))
          break label271;
        int i4 = 1;
        label156: if (paramView != null)
          break label277;
        HomeListActivity localHomeListActivity1 = HomeListActivity.this;
        ListView localListView1 = HomeListActivity.this.mLvHome;
        List localList3 = HomeListActivity.this.mList;
        int i5 = paramInt;
        MBlog localMBlog1 = (MBlog)localList3.get(i5);
        HomeListActivity localHomeListActivity2 = HomeListActivity.this;
        int i6 = paramInt;
        boolean bool4 = localHomeListActivity2.isNewCommer(i6);
        int i7 = HomeListActivity.this.mReadMode;
        localObject2 = new MBlogListItemView(localHomeListActivity1, localListView1, localMBlog1, bool1, bool2, i4, bool4, i7);
      }
      while (true)
      {
        localObject1 = localObject2;
        break label26:
        str1 = StaticInfo.mUser.uid;
        break label110:
        label271: boolean bool3 = null;
        break label156:
        label277: localObject2 = paramView;
        try
        {
          MainListItemView localMainListItemView = (MainListItemView)localObject2;
          List localList4 = HomeListActivity.this.mList;
          int i8 = paramInt;
          Object localObject3 = localList4.get(i8);
          HomeListActivity localHomeListActivity3 = HomeListActivity.this;
          int i9 = paramInt;
          boolean bool5 = localHomeListActivity3.isNewCommer(i9);
          int i10 = HomeListActivity.this.mReadMode;
          boolean bool6 = bool1;
          boolean bool7 = bool2;
          localMainListItemView.update(localObject3, bool6, bool7, bool5, i10);
        }
        catch (Exception localException)
        {
          HomeListActivity localHomeListActivity4 = HomeListActivity.this;
          ListView localListView2 = HomeListActivity.this.mLvHome;
          List localList5 = HomeListActivity.this.mList;
          int i11 = paramInt;
          MBlog localMBlog2 = (MBlog)localList5.get(i11);
          HomeListActivity localHomeListActivity5 = HomeListActivity.this;
          int i12 = paramInt;
          boolean bool8 = localHomeListActivity5.isNewCommer(i12);
          int i13 = HomeListActivity.this.mReadMode;
          localObject2 = new MBlogListItemView(localHomeListActivity4, localListView2, localMBlog2, bool1, bool2, bool3, bool8, i13);
        }
      }
    }

        代碼說明:

          代碼流程已經比較混亂,但是這裡能看到並沒有直接的inflate,而是自定義了繼承自LinearLayout的MBlogListItemView。

      MBlogListItemView   public MBlogListItemView(Context paramContext, ListView paramListView, MBlog paramMBlog, boolean paramBoolean1, boolean paramBoolean2, boolean paramBoolean3, boolean paramBoolean4, int paramInt)
  {
    super(paramContext);
    this.context = paramContext;
    this.parent = paramListView;
    this.mBlog = paramMBlog;
    String str1 = paramContext.getCacheDir().getAbsolutePath();
    this.mCacheDir = str1;
    String str2 = paramContext.getFilesDir().getAbsolutePath();
    this.mFileDir = str2;
    ((LayoutInflater)paramContext.getSystemService("layout_inflater")).inflate(2130903061, this);
    TextView localTextView1 = (TextView)findViewById(2131624016);
    this.mName = localTextView1;
    TextView localTextView2 = (TextView)findViewById(2131624041);
    this.mDate = localTextView2;
    TextView localTextView3 = (TextView)findViewById(2131624018);
    this.mContent = localTextView3;
    TextView localTextView4 = (TextView)findViewById(2131624046);
    this.mSubContent = localTextView4;
    ImageView localImageView1 = (ImageView)findViewById(2131624040);
    this.mIconV = localImageView1;
    ImageView localImageView2 = (ImageView)findViewById(2131624042);
    this.mIconPic = localImageView2;
    ImageView localImageView3 = (ImageView)findViewById(2131624044);
    this.mUploadPic1 = localImageView3;
    ImageView localImageView4 = (ImageView)findViewById(2131623979);
    this.mUploadPic2 = localImageView4;
    TextView localTextView5 = (TextView)findViewById(2131624047);
    this.tvForm = localTextView5;
    TextView localTextView6 = (TextView)findViewById(2131623989);
    this.tvComment = localTextView6;
    this.tvComment.setOnClickListener(this);
    TextView localTextView7 = (TextView)findViewById(2131623988);
    this.tvRedirect = localTextView7;
    this.tvRedirect.setOnClickListener(this);
    ImageView localImageView5 = (ImageView)findViewById(2131624049);
    this.imComment = localImageView5;
    this.imComment.setOnClickListener(this);
    ImageView localImageView6 = (ImageView)findViewById(2131624048);
    this.imRedirect = localImageView6;
    this.imRedirect.setOnClickListener(this);
    ImageView localImageView7 = (ImageView)findViewById(2131624043);
    this.imGpsIcon = localImageView7;
    ImageView localImageView8 = (ImageView)findViewById(2131624013);
    this.mPortrait = localImageView8;
    LinearLayout localLinearLayout = (LinearLayout)findViewById(2131624045);
    this.mSubLayout = localLinearLayout;
    this.mReadMode = paramInt;
    MBlogListItemView localMBlogListItemView = this;
    MBlog localMBlog = paramMBlog;
    boolean bool1 = paramBoolean1;
    boolean bool2 = paramBoolean2;
    boolean bool3 = paramBoolean4;
    int i = paramInt;
    localMBlogListItemView.update(localMBlog, bool1, bool2, bool3, i);
    this.mUploadPic1.setOnClickListener(this);
    this.mUploadPic2.setOnClickListener(this);
  }

    代碼說明:

      a).  MBlogListItemView extends LinearLayout implements MainListItemView
 

      b).  inflate(2130903061,this)這個數字代表R.layout.itemview。

 

  二、測試方案(方案五)

    按照新浪微博類似的做法進行測試。

    2.1  測試代碼

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // 開始計時
            long startTime = System.nanoTime();

            TestItemLayout item;
            if (convertView == null) {
                item = new TestItemLayout(BaseAdapterActivity.this);
            } else
                item = (TestItemLayout) convertView;
            item.icon1.setImageResource(R.drawable.icon);
            item.text1.setText(mData[position]);
            item.icon2.setImageResource(R.drawable.icon);
            item.text2.setText(mData[position]);

            // 停止計時
            long endTime = System.nanoTime();
            // 計算耗時
            long val = (endTime - startTime) / 1000L;
            Log.e("Test", "Position:" + position + ":" + val);
            if (count < 100) {
                if (val < 2000L) {
                    sum += val;
                    count++;
                }
            } else
                mTV.setText(String.valueOf(sum / 100L) + ":" + nullcount);// 顯示統計結果
            return item;
        }

 

      TestItemLayout

public class TestItemLayout extends LinearLayout {

    public TextView text1;
    public ImageView icon1;
    public TextView text2;
    public ImageView icon2;

    public TestItemLayout(Context context) {
        super(context);
        ((LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.list_item_icon_text, this);
        icon1 = (ImageView) findViewById(R.id.icon1);
        text1 = (TextView) findViewById(R.id.text1);
        icon2 = (ImageView) findViewById(R.id.icon2);
        text2 = (TextView) findViewById(R.id.text2);
    }
}

    2.2  測試結果

次數

4個子元素

10個子元素

第一次

 347

460
 

第二次

310
 

477
 

第三次

 324

508
 

第四次

339
 

492
 

第五次

 341

465

 

  三、總結
 

    從測試結果來看與ViewHolder性能非常接近,不會出現tag圖片變小的問題(關於圖片變小的問題,有朋友說是TAG中的元素對大小和位置有記憶),也能有效的減少findViewById的執行次數,這裡建議完全可以取代ViewHolder。

    關於ListView內部Adapter的心得大家可以看一下上文的總結4.1。

 

  四、考慮
 

    關於靜態內部類這裡不是很理解,是否能應用方案五還有待驗證。

 

結束
 

  優化ListView不僅僅只有對convertView的優化,還有許多這樣那樣的技巧,歡迎大家交流與分享 :)
 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved