首页 文章

对ListView性能改进的建议

提问于
浏览
0

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

<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):增长堆(frag case)为4.647MB,用于148492字节分配12-21 03 :54:35.607:D / dalvikvm(1248):GC_FOR_ALLOC释放<1K,16%免费4560K / 5368K,暂停14ms,总计15ms 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未实现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%f ree 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

这可能是由于这行代码造成的.1666658_ http://www.domain.com/ " + objNewss[position].titleImage);" . 如果评论负载明显加快 .

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

非常感谢 .

2 回答

  • 1

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

  • 1

    你没有利用这个结构 . 这是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;
    }
    

相关问题