Приложение тормозит с android:layerType=software

Я делаю очень простое приложение (в основном список с несколькими изображениями). Как правило, он очень хорошо работает на моем тестовом устройстве (Motorola Moto G со стандартным Android, который поставляется с ним).

Однако я хочу, чтобы в моем ListView были разделители с точками. Поэтому я создал файл list_divider.xml, определяющий разделитель, и установил его как разделитель, который будет использоваться в ListView. Я попробовал это на своем Moto G, но он не отображал пунктирную линию.

Поэтому я погуглил и нашел здесь решение проблемы. Отключение аппаратного ускорения для представления решило ошибку и правильно отобразило разделитель.

Однако теперь у меня другая проблема: после отключения аппаратного ускорения приложение стало лагать при прокрутке.

Есть ли решение иметь разделитель с точками и не отключать аппаратное ускорение или, по крайней мере, иметь производительность почти такую ​​​​же, как до его отключения?

Изменить: вот код адаптера, который я использую:

public class AstronautArrayAdapter extends ArrayAdapter<Astronaut> {

    public static final String TAG = "AstronautArrayAdapter";

    public AstronautArrayAdapter(Context context, List<Astronaut> objects) {
        super(context, R.layout.astronauts_list_row, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RowViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater();
            convertView = inflater.inflate(R.layout.astronauts_list_row, parent, false);

            holder = new RowViewHolder();
                holder.name = (TextView) convertView.findViewById(R.id.nameOfAustronaut);
            holder.daysInSpace = (TextView) convertView.findViewById(R.id.numberOfDaysInSpace);
            holder.country = (ImageView) convertView.findViewById(R.id.countryImage);
            holder.title = (TextView) convertView.findViewById(R.id.titleOfAstronaut);

            convertView.setTag(holder);
        } else {
            holder = (RowViewHolder) convertView.getTag();
        }

        Astronaut astronaut = getItem(position);

        holder.name.setText(astronaut.getName());
        holder.daysInSpace.setText(Integer.toString(astronaut.getDaysInSpace()));
        holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));
        holder.title.setText(astronaut.getTitle());

        return convertView;
    }

    private static class RowViewHolder {
        TextView name;
        TextView daysInSpace;
        ImageView country;
        TextView title;
    }

}

Редактировать 2: Вот два рассматриваемых файла макета:

Activity_main.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/astronautsList"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:padding="16dp"
    android:dividerHeight="3dp"
    android:divider="@drawable/list_divider"
    android:layerType="software" />

list_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line" >

    <stroke
        android:width="1px"
        android:color="@android:color/black"
        android:dashWidth="5px"
        android:dashGap="1px" />

    <size android:height="3dp" />

</shape>

person brgr    schedule 05.07.2014    source источник
comment
эта строка: holder.country.setImageBitmap(astronaut.getCountryImage(getContext())); создает впечатление, что вы, возможно, выполняете декодирование (или даже загрузку) растрового изображения в потоке пользовательского интерфейса. Ты??   -  person Budius    schedule 05.07.2014
comment
Нет. При запуске приложения я загружаю все, что хочу, и сохраняю это локально. (При запуске приложение тормозит, но я знаю, что это из-за загрузок, и оно нужно).   -  person brgr    schedule 05.07.2014
comment
сохраните его локально, что по-прежнему означает, что во время этого вызова строки растровые изображения считываются с диска (операция ввода-вывода) и декодируются (интенсивная работа ЦП). Я напишу свое предложение в ответ.   -  person Budius    schedule 05.07.2014


Ответы (2)


возможный ответ на отставание, которое вы видите:

добавьте эту строку в раздел dependencies в свой build.gradle

compile 'com.squareup.picasso:picasso:2.3.2'

и замените эту строку

holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));

с

Picasso.with(context).load(/* insert the URL here */).into(holder.country);

и удалите код, который загружает все изображения и сохраняет их локально. Picasso автоматически загружает/декодирует растровые изображения и управляет дисковым и оперативным кешем для вас.

пс.:

если вы не используете Gradle:

  1. Вы должны перейти на Android-Studio и использовать Gradle
  2. забудьте, что я сказал о добавлении строки в файл gradle, и просто загрузите файл jar с их веб-сайта, поместите в папку libs и не забудьте изменить настройки проекта, чтобы убедиться, что jar входит в ваш APK (честно говоря, я не помню, как работают эти настройки, потому что я давно отказался от Eclipse)
person Budius    schedule 05.07.2014
comment
Относительно № 2: поместите его в libs, и ADT сделает это за вас, к счастью, Google не так сильно отказался от ADT. - person TWiStErRob; 29.07.2014

Как вы не упомянули, реализовали ли вы шаблон ViewHolder?

Поскольку ListView перерабатывает представления, он должен раздувать макет и вставлять в него любой текст и изображения. Обычно вы вызываете findViewById в этом разделе кода, что довольно дорого. Паттерн ViewHolder решает эту проблему, и его легко реализовать.

См. здесь отличный учебник от Google

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

person Graham Smith    schedule 05.07.2014
comment
Да, я использую ViewHolder, и он все еще отстает. - person brgr; 05.07.2014
comment
Сделать внутренний класс статическим - person Graham Smith; 05.07.2014
comment
Вам не нужен частный, но в противном случае код выглядит хорошо, возможно, вам понадобится файл макета, чтобы быть уверенным. - person Graham Smith; 05.07.2014
comment
Добавлю, минуточку ;) - person brgr; 05.07.2014
comment
Хорошо, увидев другие комментарии, возьмите эту библиотеку под названием Picasso, она действительно проста и очень хорошо обрабатывает загрузку изображений square. github.io/picasso - person Graham Smith; 05.07.2014
comment
Поскольку я ничего не нашел на его веб-сайте, как вы думаете, он хорошо работает и с отключенным аппаратным ускорением (потому что это то, что мне нужно, когда я хочу получить пунктирные линии)? Потому что с аппаратным ускорением мое приложение уже работает хорошо. - person brgr; 05.07.2014
comment
Я думаю, это потому, что вы декодируете растровые изображения из файла, и это будет действительно здорово с ускорением HW, но плохо без него. Загрузите банку и поместите ее в папку libs, а затем используйте пример кода в своем адаптере. Передайте URL-адрес изображения, а не загружайте их в начале, поскольку в него встроена отличная система кэширования. - person Graham Smith; 05.07.2014