Предложение по улучшению производительности ListView

Я использую пользовательский вид списка, чтобы показать изображение и текст. Ниже приведен файл макета для моего элемента представления списка и код позади него. Я объясню свою проблему в нижней части поста.

<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;
    }

Эти фрагменты кода работают отлично, изображение и текст загружаются хорошо. Однако, когда количество элементов увеличивается, время загрузки также увеличивается. Экран будет пустым в ожидании загрузки представления. Ниже приведен логарифм.

12-21 03:54:20.827: D/OpenGLRenderer(1248): включение режима отладки 0

12-21 03:54:20.955: Я/Хореограф(1248): Пропущено 36 кадров! Приложение может выполнять слишком много работы в своем основном потоке.

12-21 03:54:24.991: D/dalvikvm(1248): GC_FOR_ALLOC освободил 467 КБ, 14% освободил 4447 КБ/5116 КБ, пауза 8 мс, всего 17 мс

12-21 03:54:35.587: D/dalvikvm(1248): GC_FOR_ALLOC освобождено 263 КБ, 16% свободно 4416 КБ/5220 КБ, пауза 7 мс, всего 9 мс

12-21 03:54:35.591: I/dalvikvm-heap(1248): увеличить размер кучи (фрагмент) до 4,647 МБ для выделения 148492 байт.

12-21 03:54:35.607: D/dalvikvm(1248): GC_FOR_ALLOC освобождено ‹1K, 16% свободно 4560K/5368K, пауза 14 мс, всего 15 мс

12-21 03:54:43.363: D/dalvikvm(1248): GC_FOR_ALLOC освободил 322К, 18% освободил 4415К/5368К, пауза 8мс, всего 8мс

12-21 03:54:44.611: D/dalvikvm(1248): GC_FOR_ALLOC освобождено 281K, 18% свободно 4415K/5368K, пауза 8 мс, всего 9 мс

12-21 03:54:46.531: W/EGL_genymotion(1248): eglSurfaceAttrib не реализован

12-21 03:54:48.115: D/dalvikvm(1248): GC_FOR_ALLOC освобождено 284 КБ, 18 % свободно 4420 КБ/5368 КБ, пауза 8 мс, всего 10 мс

12-21 03:54:49.983: D/dalvikvm(1248): GC_FOR_ALLOC освободил 323 КБ, 18% освободил 4429 КБ/5368 КБ, пауза 6 мс, всего 6 мс

12-21 03:54:50.339: D/dalvikvm(1248): GC_FOR_ALLOC освобождено 280 тыс., 18% свободно 4439 тыс./5368 тыс., пауза 11 мс, всего 11 мс

12-21 03:54:50.551: Я/Хореограф(1248): Пропущено 1523 кадра! Приложение может выполнять слишком много работы в своем основном потоке.

12-21 03:54:51.263: D/dalvikvm(1248): GC_FOR_ALLOC освободил 288К, 17% освободил 4500К/5368К, пауза 8мс, всего 9мс

12-21 03:54:54.115: D/dalvikvm(1248): GC_FOR_ALLOC освободил 326 КБ, 17% освободил 4497 ​​КБ/5368 КБ, пауза 7 мс, всего 9 мс

12-21 03:54:54.531: D/dalvikvm(1248): GC_FOR_ALLOC освободил 281K, 17% освободил 4496K/5368K, пауза 10 мс, всего 10 мс

12-21 03:54:55.871: D/dalvikvm(1248): GC_FOR_ALLOC освободил 287 КБ, 17% освободил 4506 КБ/5368 КБ, приостановил 8 мс, всего 9 мс

12-21 03:54:56.591: D/dalvikvm(1248): GC_FOR_ALLOC освободил 324 КБ, 17% освободил 4506 КБ/5368 КБ, пауза 7 мс, всего 8 мс

12-21 03:54:57.339: D/dalvikvm(1248): GC_FOR_ALLOC освободил 281K, 17% освободил 4506K/5368K, пауза 7 мс, всего 8 мс

Это может быть связано с тем, что «Bitmap titleImage = Global.GetBitmapFromURL("http://www.domain.com/ " + objNewss[position].titleImage);" эта строка кода. Если прокомментировать, то загрузка значительно быстрее.

Могу я узнать, есть ли у кого-нибудь из экспертов лучшее предложение для меня? Еще лучше, если можно реализовать асинхронную загрузку, такую ​​​​как groupon и т. Д., Где она загружается и показывается построчно, что не будет мешать работе пользователя.

Большое спасибо.


person TPG    schedule 21.12.2014    source источник


Ответы (2)


Похоже, что Global.GetBitmapFromURL работает в основном потоке. Любой сетевой запрос должен выполняться в отдельном потоке, поэтому вы должны переместить его в AsyncTask или Loader, который решит вашу проблему.

person Dara    schedule 21.12.2014

Вы не используете структуру. Это копия класса EfficientAdapter, написанная командой разработчиков Android.

Во время оценки 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;
}
person mrres1    schedule 21.12.2014