ListView的優化:
(前兩點都是利用ListView的自身優化機制優化【緩存優化】)
1.利用ListView自身的緩存機制,他會緩存條目中的一個條目item,當listview第一屏顯示完成之后,就會出現一個緩存條目,其實就是BaseAdapter里面的public View getView(int position, View convertView, ViewGroup parent)。
2.減少findViewById()的次數,findViewById是一個相對比較耗性能的操作,因為這個操作每次都需要到布局中去查找文件。把item里面的控件封裝成一個javaBean,當item條目被加載的時候就去找到對應的控件。
3.利用時間去換取時間,比如開機優化,把一些重要的程序先啟動了,啟動完系統之后再啟動其他程序。
4.利用空間去換取時間,把要獲取的數據先加載到內存里面,再處理數據的時候,直接從內存中獲取。
例如:減少數據庫的頻繁打開和關閉和減少查詢的次數。
Demo:需求: 程序鎖,將手機中所有的應用顯示出來,是否是帶鎖的應用用數據庫進行存儲,通過ListView顯示。
3 import java.util.List; 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.os.Handler; 8 import android.os.Message; 9 import android.util.Log; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.view.animation.TranslateAnimation; 14 import android.widget.AdapterView; 15 import android.widget.AdapterView.OnItemClickListener; 16 import android.widget.BaseAdapter; 17 import android.widget.ImageView; 18 import android.widget.ListView; 19 import android.widget.RelativeLayout; 20 import android.widget.TextView; 21 22 import com.android.hzy.mobilesafe.R; 23 import com.android.hzy.mobilesafe.dao.AppLockDao; 24 import com.android.hzy.mobilesafe.domain.AppInfo; 25 import com.android.hzy.mobilesafe.engine.AppInfoService; 26 27 public class AppLockManagerActivity extends Activity { 28 29 protected static final int SUCCESS_GET_APPLICATION = 0; 30 private ListView lv_applockmanager; 31 private RelativeLayout rl_loading; 32 private AppInfoService appInfoService; 33 private List<AppInfo> appInfos; 34 35 private List<String> appLocks; // 程序鎖應用集合 36 37 private AppLockManagerAdapter mAdapter; 38 private AppLockDao appLockDao; 39 private Handler mHandler = new Handler(){ 40 41 public void handleMessage(Message msg) { 42 switch (msg.what) { 43 case SUCCESS_GET_APPLICATION: 44 appLocks = appLockDao.findAll(); 45 mAdapter = new AppLockManagerAdapter(); 46 lv_applockmanager.setAdapter(mAdapter); 47 rl_loading.setVisibility(View.GONE); 48 break; 49 50 default: 51 break; 52 } 53 } 54 55 }; 56 57 @Override 58 protected void onCreate(Bundle savedInstanceState) { 59 // TODO Auto-generated method stub 60 super.onCreate(savedInstanceState); 61 setContentView(R.layout.app_lock_manager); 62 63 lv_applockmanager = (ListView) findViewById(R.id.lv_applockmanager); 64 rl_loading = (RelativeLayout) findViewById(R.id.rl_loading); 65 appInfoService = new AppInfoService(this); 66 67 new Thread() { 68 public void run() { 69 appInfos = appInfoService.getAppInfos(); 70 Message msg = new Message(); 71 msg.what = SUCCESS_GET_APPLICATION; 72 mHandler.sendMessage(msg); 73 }; 74 }.start(); 75 76 appLockDao = new AppLockDao(this); 77 78 lv_applockmanager.setOnItemClickListener(new MyOnItemClickListener()); 79 } 80 81 /**********listview條目點擊事件*************************/ 82 private final class MyOnItemClickListener implements OnItemClickListener{ 83 84 @Override 85 public void onItemClick(AdapterView<?> parent, View view, int position, 86 long id) { 87 // TODO Auto-generated method stub 88 // 通過ViewHolder的iv_lock 減少findViewById 89 ImageView iv_lock = ((ViewHolder)view.getTag()).iv_lock; 90 AppInfo appInfo = (AppInfo) mAdapter.getItem(position); 91 // boolean isLockApp = appLockDao.isLockApp(appInfo.getPackagename()); 減少數據庫的查詢 92 boolean isLockApp = appLocks.contains(appInfo.getPackagename()); 93 if (isLockApp) { 94 // 如果有鎖 就解鎖 95 appLockDao.delete(appInfo.getPackagename()); 96 // 解鎖需要將集合中帶鎖應用的移除 97 appLocks.remove(appInfo.getPackagename()); 98 iv_lock.setImageResource(R.drawable.unlock); 99 } else { 100 // 如果沒有鎖 就加鎖 101 appLockDao.add(appInfo.getPackagename()); 102 // 加鎖需要將有鎖的集合中添加該應用 103 appLocks.add(appInfo.getPackagename()); 104 iv_lock.setImageResource(R.drawable.lock); 105 } 106 107 // 設置動畫 108 TranslateAnimation animation = new TranslateAnimation(0, 80, 0, 0); 109 animation.setDuration(300); 110 view.startAnimation(animation); 111 } 112 113 } 114 115 /** 116 * 適配器 117 */ 118 public final class AppLockManagerAdapter extends BaseAdapter{ 119 120 private LayoutInflater mInflater; 121 122 public AppLockManagerAdapter() { 123 // TODO Auto-generated constructor stub 124 mInflater = getLayoutInflater(); 125 } 126 127 @Override 128 public int getCount() { 129 // TODO Auto-generated method stub 130 return appInfos.size(); 131 } 132 133 @Override 134 public Object getItem(int position) { 135 // TODO Auto-generated method stub 136 return appInfos.get(position); 137 } 138 139 @Override 140 public long getItemId(int position) { 141 // TODO Auto-generated method stub 142 return position; 143 } 144 145 @Override 146 public View getView(int position, View convertView, ViewGroup parent) { 147 // TODO Auto-generated method stub 148 View view = null; 149 ViewHolder holder = null; 150 if (convertView != null) { 151 view = convertView; 152 holder = (ViewHolder) view.getTag(); 153 Log.i("i", " convertView != null 緩存不等於空 使用緩存"); 154 155 } else { 156 Log.i("i", " convertView == null 緩存等於空"); 157 view = mInflater.inflate(R.layout.app_lock_manager_item, null); 158 holder = new ViewHolder(); 159 holder.iv_appicon = (ImageView) view.findViewById(R.id.iv_appicon); 160 holder.tv_appname = (TextView) view.findViewById(R.id.tv_appname); 161 holder.iv_lock = (ImageView) view.findViewById(R.id.iv_lock); 162 view.setTag(holder); 163 } 164 AppInfo appInfo = appInfos.get(position); 165 166 ImageView iv_appicon = holder.iv_appicon; 167 TextView tv_appname = holder.tv_appname; 168 ImageView iv_lock = holder.iv_lock; 169 170 iv_appicon.setImageDrawable(appInfo.getApp_icon()); 171 tv_appname.setText(appInfo.getApp_name()); 172 173 // boolean isLockApp = appLockDao.isLockApp(appInfo.getPackagename()); 174 boolean isLockApp = appLocks.contains(appInfo.getPackagename()); // 此功能優化后 不用每次查詢數據庫 直接將所有有鎖的程序都放入集合中存儲 175 if(isLockApp){ 176 iv_lock.setImageResource(R.drawable.lock); 177 }else{ 178 iv_lock.setImageResource(R.drawable.unlock); 179 } 180 181 return view; 182 } 183 184 } 185 186 static class ViewHolder{ 187 ImageView iv_appicon; 188 TextView tv_appname; 189 ImageView iv_lock; 190 } 191 }
效果如上圖,當第一次加載ListView里面條目時,我們所能看見的都是沒有緩存的,當我們往下滑動后,控件都是使用緩存中的控件,減少了findViewById的次數