Android - декларативный и программный интерфейс - PullRequest
18 голосов
/ 01 апреля 2010

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

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

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

Ответы [ 3 ]

23 голосов
/ 01 апреля 2010

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

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

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

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

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

3 голосов
/ 13 апреля 2012

Я провел ОЧЕНЬ неформальные / хакерские тесты по этому поводу и обнаружил, что при использовании программного подхода, хотя с ним не так приятно работать, он экономил от трети до половины общего времени, затрачиваемого на это. Тест проводился только на 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);
}

}

3 голосов
/ 28 июля 2011

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

Мой Логкат говорит:

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

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

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);
        }       
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...