当前位置: 代码迷 >> Android >> Android性能优化系列-Improving Layout Performance(4)
  详细解决方案

Android性能优化系列-Improving Layout Performance(4)

热度:222   发布时间:2016-04-28 05:42:51.0
Android性能优化系列---Improving Layout Performance(四)

?

? ? ? ?Making ListView Scrolling Smooth

?

? ? ? ? 让ListView平滑滚动的关键在于将程序的主线程(UI线程)从大量的处理中解脱出来。要要保证用单独的线程来进行磁盘,网络或SQL操作。想要测试你的程序的状态, 你可以开启StrictMode。

?

? ? ? ? Use a Background Thread

? ? ? ? ?使用后台线程(“工作线程”)可移除主线程中的压力,这样可以使得UI线程可以专注于描绘UI。大多数时候,AsycnTask实现了一种简单的把需要做的事情与main thread分离的方法。AsyncTask自动将所有execute()请求排成队列并按顺序执行他们。这种行为对一个特定进程来说是全局性的,这意味着你不必担心创建自己的线程池。

? ? ? ? ?下方所示的简单代码中,利用AsyncTask在后台线程中加载图像,然后一旦完成便更新UI。当图片正在加载时可以显示一个Spinner进度条来代替正在加载的图像。

?

? ? ? ? // Using an AsyncTask to load the slow images in a background thread

? ? ? ? new AsyncTask<ViewHolder, Void, Bitmap>() {

? ? ? ? ? ? ? ? private ViewHolder v;

?

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? protected Bitmap doInBackground(ViewHolder... params) {

? ? ? ? ? ? ? ? ? ? ? ? ?v = params[0];

? ? ? ? ? ? ? ? ? ? ? ? ?return mFakeImageLoader.getImage();

? ? ? ? ? ? ? ? ?}

?

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? protected void onPostExecute(Bitmap result) {

? ? ? ? ? ? ? ? ? ? ? ? ? super.onPostExecute(result);

? ? ? ? ? ? ? ? ? ? ? ? ? ?if (v.position == position) {

? ? ? ? ? ? ? ? ? ? ? ? ? // If this item hasn't been recycled already, hide the

? ? ? ? ? ? ? ? ? ? ? ? ? // progress and set and show the image

? ? ? ? ? ? ? ? ? ? ? ? ? v.progress.setVisibility(View.GONE);

? ? ? ? ? ? ? ? ? ? ? ? ? v.icon.setVisibility(View.VISIBLE);

? ? ? ? ? ? ? ? ? ? ? ? ? v.icon.setImageBitmap(result);

? ? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? ?}

? ? ? ? ? }.execute(holder);

?

? ? ? ? ?从 Android 3.0 (API level 11)开始,对于AsyncTask有个新特性:在多核处理器的情况下,我们可以使用executeOnExecutor() 来替代execute(),这样系统会根据当前设备的内核数量同时执行多个任务。

?

? ? ? ? ?Hold View Objects in a View Holder

? ? ? ? 你在滑动ListView时可能需要频繁地调用findViewById(),这样会降低性能。尽管Adapter会因为循环机制返回一个创建好的View。你仍然需要查找到这些组件并更新它,避免这样的重复,可使用“ViewHolder”设计模式。

? ? ? ? ?一个ViewHolder对象缓存Layout里的每一个组件视图。因此你能立即的访问这些视图而不需要重复查询他们。首页,你需要产生一个ViewHolder类,如下:

? ? ? ? ?static class ViewHolder {

? ? ? ? ? ? ? ? ? ?TextView text;

? ? ? ? ? ? ? ? ? ?TextView timestamp;

? ? ? ? ? ? ? ? ? ?ImageView icon;

? ? ? ? ? ? ? ? ? ?ProgressBar progress;

? ? ? ? ? ? ? ? ? ?int position;

? ? ? ? ? }

?

? ? ? ? 这样之后,我们可以填充这个ViewHolder,并且保存到tag属性里。

?

? ? ? ? ? ? ViewHolder holder = new ViewHolder();

? ? ? ? ? ? holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);

? ? ? ? ? ? holder.text = (TextView) convertView.findViewById(R.id.listitem_text);

? ? ? ? ? ? holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);

? ? ? ? ? ? holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);

? ? ? ? ? ?convertView.setTag(holder);

?

? ? ? ? ? 那么我们就可以直接访问里面的数据了,省去了重复查询,提升了性能。

  相关解决方案