Подтвердить что ты не робот

Android - декларативный и программный интерфейс

Кто-нибудь видел или компилировал тесты, сравнивающие декларативный (XML) и программно созданный пользовательский интерфейс в Android?

Есть вещи, которые Google сделал для ускорения декларативного подхода, но у вас все еще есть шаг инфляции макета, выполняемый во время выполнения.

Вы когда-нибудь переключали (или считали) меняя свой пользовательский интерфейс от декларативного на программный по любой причине?

4b9b3361

Ответ 1

Очень мало инфляции компоновки выполняется во время выполнения. Как указано в документах API LayoutInflator API:

По соображениям производительности просмотр инфляция в значительной степени зависит от предварительная обработка XML файлов, которые сделано во время сборки. Следовательно, это в настоящее время невозможно использовать LayoutInflater с XmlPullParser над простым XML файлом во время выполнения

Если вы посмотрите на source, многие из них выводятся из хэш-карты на основе их тега XML.

В ответ на ваш вопрос о том, сравнивал ли я надуватель, я должен сказать "нет". Лично я нахожу идею бенчмаркинга раздувного устройства разметки в Android для вашего приложения, чтобы быть эквивалентом бенчмаркинга DOM-парсера в Firefox для вашего сайта. Я не думаю, что упражнение бессмысленно, но у вас должна быть гораздо лучшая причина, чем "мой макет активности слишком сложный для надувного устройства"...

Если вам нужен динамически сгенерированный макет, вам лучше всего создавать его программно. Если ваше представление просто затягивается, вы должны упростить свой XML-представление.

Ответ 2

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

Мой Logcat говорит:

updating UI inflating on demand >> 2136mS
updating UI reusing from pool >> 937mS

Вот мой класс, просто не против моего неуклюжего стиля Java-кодирования, я программист на С++.

import java.util.ArrayList;
import java.util.List;
import android.view.LayoutInflater;
import android.view.View;

    public class ViewPool {
        private List<View> mViews;
        private LayoutInflater mInf;
        private int mIdx;
        private int mResource;

        /**
         * Constructor, gives Inflater and resource ID to inflate
         * @param mInf Layout inflater
         * @param rID  Resource ID of view to inflate
         * @para number number of views that must inflate on first initialization
         */
        public ViewPool(LayoutInflater mInf, int rID, int number) {
            super();

            int idx;
            mViews = new ArrayList<View>();
            this.mInf = mInf;
            mResource = rID;
            mIdx=0; // index of first used item

            for(idx=0; idx<number;++idx)
            {
                mViews.add((View)mInf.inflate(mResource, null));
            }

        }

        /**
         * Start from first item of pool
         */
        public void Reset()
        {
            mIdx=0;
        }

        /**
         * Get a view from pool, if no more views on pool, inflate more 
         * @return
         */
        public View GetView()
        {
            View retval;

            retval = mViews.get(mIdx);
            ++mIdx;

            if(mIdx == mViews.size()) // no more views in pool??
                mViews.add((View)mInf.inflate(mResource, null)); // inflate more

            return(retval);
        }       
    }

Ответ 3

Я сделал некоторые ОЧЕНЬ неофициальные/хакерские тесты на этом и обнаружил, что с программным подходом, хотя и не так приятно работать, сбрил между трети с половиной от общего времени. Тест проводился только на Samsung 7 "Galaxy, а не на AVD.

Как я уже сказал, это был очень неофициальный/хакерский тест (как вы увидите по коду), с очень ограниченными обстоятельствами, такого рода вещи, которые вы собрали быстро, чтобы удовлетворить свое любопытство, а не обычно для общественного потребления.

R.layout.ll и R.layout.tv - это простые файлы макета, содержащие пустые LinearLayouts и TextViews соответственно.

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

package com.inflatervscode;

import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;

public class InflaterVSCodeActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

// Generates a few nested LinearLayouts/TextViews, a number of
// times, and works out how many milliseconds this took.
@Override
public void onResume() {
    super.onResume();
    setContentView(R.layout.main);

    int num_repeats = 500; // Change this to however many times you want to
                           // create a set of nested views.
    LinearLayout masterLL = (LinearLayout)findViewById(R.id.test);
    TextView results = (TextView)findViewById(R.id.results);

    Calendar c = Calendar.getInstance();
    long startTime = c.getTimeInMillis();

    for (int i=0;i<num_repeats;i++) {
            // Replace the section below with LinearLayout fll = new LinearLayout(this); etc
        LinearLayout fll = (LinearLayout)getLayoutInflater().inflate(R.layout.ll, null);
        LinearLayout sll = (LinearLayout)getLayoutInflater().inflate(R.layout.ll, null);
        LinearLayout tll = (LinearLayout)getLayoutInflater().inflate(R.layout.ll, null);
        TextView tv = (TextView)getLayoutInflater().inflate(R.layout.tv, null);

        tv.setText(i+"");
        tll.addView(tv);
        sll.addView(tll);
        fll.addView(sll);
        masterLL.addView(fll);
    }

    c = Calendar.getInstance();
    long endTime = c.getTimeInMillis();

    String tt = Long.toString((endTime-startTime));

    results.setText("Results for "+num_tests+" tests:\n\nStart:"+Long.toString(startTime)+"\nEnd  :"+Long.toString(endTime)+"\n\nDifference (ms):"+tt);
}

}