標籤:listview載入最佳化 效能最佳化
問題分析
在移動端項目開發中,基於載入大資料量的原因,經常出現記憶體溢出的現象,那麼減少記憶體佔用,在真實開發中著實很重要,下面介紹下ListView載入資料量大時解決思路:
我們應該碰到過這樣的情況,對於載入的listview,我們慢慢滑動資料時,系統載入資料沒有問題,但是當加快滑動資料時,就會出現記憶體溢出的問題(這裡不考慮分頁載入方法)。總結這是因為手機螢幕顯示的原因,每次載入資料是有限的,慢慢滑動資料,在載入資料的同時,系統能有時間回收不用的記憶體,才不會暴露問題,但是,加快滑動,記憶體回收GC來不及,慢慢記憶體就滿了。知道了原因,加大記憶體,減慢滑動速度顯然不是好的方案,實現記憶體重複使用才是最重要的。
解決方案
我們知道,資料最後顯示在手機螢幕,是通過Adapter適配器來實現的,在其預設實現方法getView()方法中,我們實現如下代碼:
//有多少個條目被顯示,這個方法就會被調用多少次@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {View view;ViewHolder holder;//1.減少記憶體中view對象建立的個數(最佳化listView,避免記憶體溢出)if(convertView==null){Log.i(TAG,"建立新的view對象:"+position);//把一個布局檔案轉化成 view對象。view = View.inflate(getApplicationContext(), R.layout.list_item_callsms, null);//2.減少子孩子查詢的次數 記憶體中對象的地址。holder = new ViewHolder();holder.tv_number = (TextView) view.findViewById(R.id.tv_black_number);holder.tv_mode = (TextView) view.findViewById(R.id.tv_block_mode);holder.iv_delete = (ImageView) view.findViewById(R.id.iv_delete);//當孩子生出來的時候找到他們的引用,存放在記事本,放在父親的口袋view.setTag(holder);}else{Log.i(TAG,"廚房有曆史的view對象,複用曆史緩衝的view對象:"+position);view = convertView;holder = (ViewHolder) view.getTag();//通過封裝成對象的方式效能最佳化5%,很小,這裡不給出Holder類,不如記憶體位址複用效果顯著}holder.tv_number.setText(infos.get(position).getNumber());String mode = infos.get(position).getMode();//刪除事件響應,這裡留著以後用holder.iv_delete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {AlertDialog.Builder builder = new Builder(CallSmsSafeActivity.this);builder.setTitle("警告");builder.setMessage("確定要刪除這條記錄嗎?");//DialogInterface介面類方法builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {//刪除資料庫的內容dao.delete(infos.get(position).getNumber());//更新介面。infos.remove(position);//通知listview資料配接器更新adapter.notifyDataSetChanged();}});builder.setNegativeButton("取消", null);builder.show();}});return view;}實現方法看程式碼分析。順便提一下,代碼中有刪除作業碼,重點看在增加刪除後資料如何更新到ListView中的,就是adapter.notifyDataSetChanged()方法。
Android載入資料ListView最佳化記憶體實現