【问题标题】:Suggestion for ListView performance improvementListView性能提升建议
【发布时间】:2015-02-19 14:31:22
【问题描述】:

我正在使用自定义列表视图来显示图像和文本。下面是我的列表视图项的布局文件和后面的代码。我将在帖子底部解释我的问题。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="5dp"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/imgTitleImage"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:scaleType="fitXY" />

    <TextView
        android:id="@+id/tvNewsTitle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/imgTitleImage"
        android:layout_alignStart="@+id/imgTitleImage"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:paddingLeft="10dp"
        android:paddingStart="10dp"
        android:paddingRight="10dp"
        android:paddingEnd="10dp"
        android:paddingTop="2dp"
        android:paddingBottom="2dp"
        android:gravity="top|start"
        android:textColor="#FFFFFF"         
        android:background="#80000000" />
</RelativeLayout>

以下是将必要信息加载到列表视图中的后端代码。

public View getView(final int position, View convertView, ViewGroup parent) 
    {
        SessionManagement sessionmanagement = new SessionManagement(context);
        ViewHolder holder = null;

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.news_item, null);
            holder = new ViewHolder();
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Touch on view handle                              
                ObjNews objNews = objNewss[position];

                Intent intent = new Intent(activity, NewsViewActivity.class);       

                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                intent.putExtra("newsId", String.valueOf(objNews.newsId));
                intent.putExtra("type", String.valueOf(Config.NEWS_BRANCH));

                context.startActivity(intent);
            }

        });

        holder.imageView = (ImageView)convertView.findViewById(R.id.imgTitleImage);

        //calculate the screen size and image ratio
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);

        int width = size.x;
        float screenRatio = width / 320f;

        holder.imageView.getLayoutParams().height = (int)(75f * screenRatio);
        holder.imageView.getLayoutParams().width = (int)(320f * screenRatio);

        Bitmap titleImage = Global.GetBitmapFromURL("http://www.domain.com/" + objNewss[position].titleImage);

        if(titleImage != null)
        {
            holder.imageView.setImageBitmap(titleImage);
        }   
        else
        {
            holder.imageView.setImageDrawable(context.getResources().getDrawable(R.drawable.news_title_default));    
        }

        //customizing view
        holder.textView = (TextView)convertView.findViewById(R.id.tvNewsTitle);
        holder.textView.setText(objNewss[position].title);                     

        return convertView;
    }

这些代码运行良好,图像和文本加载良好。但是,当项目数增加时,加载时间也增加了。屏幕将是空白的,等待视图加载。下面是获取的logcat。

12-21 03:54:20.827:D/OpenGLRenderer(1248):启用调试模式 0

12-21 03:54:20.955:I/Choreographer(1248):跳过 36 帧!这 应用程序可能在其主线程上做了太多工作。

12-21 03:54:24.991: D/dalvikvm(1248): GC_FOR_ALLOC 释放 467K, 14% 免费4447K/5116K,暂停8ms,共17ms

12-21 03:54:35.587: D/dalvikvm(1248): GC_FOR_ALLOC 释放 263K, 16% 免费4416K/5220K,暂停7ms,共9ms

12-21 03:54:35.591: I/dalvikvm-heap(1248): 将堆(碎片案例)增长到 4.647MB 分配 148492 字节

12-21 03:54:35.607: D/dalvikvm(1248): GC_FOR_ALLOC 释放

12-21 03:54:43.363: D/dalvikvm(1248): GC_FOR_ALLOC 释放 322K, 18% 免费4415K/5368K,暂停8ms,共8ms

12-21 03:54:44.611: D/dalvikvm(1248): GC_FOR_ALLOC 释放 281K, 18% 免费4415K/5368K,暂停8ms,共9ms

12-21 03:54:46.531: W/EGL_genymotion(1248): eglSurfaceAttrib not 实施

12-21 03:54:48.115: D/dalvikvm(1248): GC_FOR_ALLOC 释放 284K, 18% 免费4420K/5368K,暂停8ms,共10ms

12-21 03:54:49.983: D/dalvikvm(1248): GC_FOR_ALLOC 释放 323K, 18% 免费4429K/5368K,暂停6ms,共6ms

12-21 03:54:50.339: D/dalvikvm(1248): GC_FOR_ALLOC 释放 280K, 18% 免费4439K/5368K,暂停11ms,共11ms

12-21 03:54:50.551:I/Choreographer(1248):跳过 1523 帧!这 应用程序可能在其主线程上做了太多工作。

12-21 03:54:51.263: D/dalvikvm(1248): GC_FOR_ALLOC 释放 288K, 17% 免费4500K/5368K,暂停8ms,共9ms

12-21 03:54:54.115: D/dalvikvm(1248): GC_FOR_ALLOC 释放 326K, 17% 免费4497K/5368K,暂停7ms,共9ms

12-21 03:54:54.531: D/dalvikvm(1248): GC_FOR_ALLOC 释放 281K, 17% 免费4496K/5368K,暂停10ms,共10ms

12-21 03:54:55.871: D/dalvikvm(1248): GC_FOR_ALLOC 释放 287K, 17% 免费4506K/5368K,暂停8ms,共9ms

12-21 03:54:56.591: D/dalvikvm(1248): GC_FOR_ALLOC 释放 324K, 17% 免费4506K/5368K,暂停7ms,共8ms

12-21 03:54:57.339: D/dalvikvm(1248): GC_FOR_ALLOC 释放 281K, 17% 免费4506K/5368K,暂停7ms,共8ms

这可能是由于“位图 titleImage = Global.GetBitmapFromURL("http://www.domain.com/" + objNewss[position].titleImage);"这行代码。如果评论加载明显更快。

我可以知道是否有任何专家对我有更好的建议吗?如果可以实现异步加载,如 groupon 等,它会更好地加载并逐行显示,这不会干扰用户体验。

非常感谢。

【问题讨论】:

    标签: android performance android-listview


    【解决方案1】:

    似乎 Global.GetBitmapFromURL 正在主线程上运行。任何网络请求都应在单独的线程上完成,因此您应该将其移至 AsyncTask 或 Loader 以解决您的问题。

    【讨论】:

      【解决方案2】:

      您没有使用该结构。这是由 Android 开发团队编写的 EfficientAdapter 类的副本。

      在评估convertView 期间,您应该分配您的holder 值。

      通过在每次调用的条件之后赋值。

      WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display display = wm.getDefaultDisplay();
      
      Point size;
      
      float ratio = -1;
      
      //calculate the screen size and image ratio
      void float getRatio()
      {
          if(ratio == -1)
          {
              size = new Point();
      
              display.getSize(size);
      
              int width = size.x;
      
              ratio = width / 320f;
          }
      
          return ratio;
      }
      
      Bitmap titleImage;
      
      Drawable news_title_default = context.getResources().getDrawable(R.drawable.news_title_default);
      
      public View getView(final int position, View convertView, ViewGroup parent) 
      {
          ViewHolder holder = null;
      
          if (convertView == null) {
              convertView = inflater.inflate(R.layout.news_item, null);
              holder = new ViewHolder();
      
              // assign the holder values
              holder.imageView = (ImageView)convertView.findViewById(R.id.imgTitleImage);
              holder.textView = (TextView)convertView.findViewById(R.id.tvNewsTitle);
      
              convertView.setTag(holder);
          } else {
              holder = (ViewHolder)convertView.getTag();
          }
      
          convertView.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  //Touch on view handle                              
                  ObjNews objNews = objNewss[position];
      
                  Intent intent = new Intent(activity, NewsViewActivity.class);       
      
                  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      
                  intent.putExtra("newsId", String.valueOf(objNews.newsId));
                  intent.putExtra("type", String.valueOf(Config.NEWS_BRANCH));
      
                  context.startActivity(intent);
              }
      
          });
      
          holder.imageView.getLayoutParams().height = (int)(75f * getRatio());
          holder.imageView.getLayoutParams().width = (int)(320f * getRatio());
      
          titleImage = Global.GetBitmapFromURL("http://www.domain.com/" + objNewss[position].titleImage);
      
          if(titleImage != null)
          {
              holder.imageView.setImageBitmap(titleImage);
          }   
          else
          {
              holder.imageView.setImageDrawable(news_title_default);    
          }
      
          //customizing view
      
          holder.textView.setText(objNewss[position].title);                     
      
          return convertView;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-08
        • 1970-01-01
        • 2018-09-23
        • 2018-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多