Производительность Android: добавление вида программно и установка представления в GONE/VISIBLE

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

В настоящее время в моем макете вид устанавливается на android:visibility="GONE", который я изменяю на VISIBLE в зависимости от SharedPreference. Это позволяет мне узнать, как приложение работает при первых запусках.

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

Теперь я думаю об альтернативе: что, если бы я только добавил свой просмотр в первый запуск, но программно, в свой фрагмент onCreateView. Это должно позволить виду не накачиваться при последующих запусках, но не будет ли раздувать представление программным путем, подразумевая плохую производительность при первых запусках?

Ответ 1

Итак, чтобы ответить на мой вопрос, я использовал инструмент DDMS TraceView для отслеживания вызовов из моего фрагмента onAttach до его onResume. Это позволило мне увидеть, какая реализация менее эффективна.

Чтобы выполнить тест, у меня был простой RelativeLayout с FrameLayout внутри него (показано все время). Я использовал индивидуальный макет, который нужно добавлять каждый раз, либо программно, либо с видимостью GONE в моем файле макета. Пользовательский макет состоял из RelativeLayout с 4 дочерними элементами (ImageView, TextView, View и Button).

My onCreateView был следующим, позволяя приложению раздувать правильный макет на основе двух констант static final boolean для изменения макетов.

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    LinearLayout root;
    if(INFLATE_PROGRAMMATICALY) {
        root = (LinearLayout) inflater.inflate(R.layout.fragment_test_prgmcly, container, false);
        if(SHOULD_FYI_VIEW_BE_SHOWN) {
            View tutoView = inflater.inflate(R.layout.inner_view, root, false);
            root.addView(tutoView);
        }
    } else {
        root = (LinearLayout) inflater.inflate(R.layout.fragment_test_gone,container,false);
        if(SHOULD_FYI_VIEW_BE_SHOWN) {
            View tutoView = root.findViewById(R.id.RL_inner_view);
            tutoView.setVisibility(View.VISIBLE);
        }
    }
    return root;
}

Это приводит к следующим результатам:

Когда дополнительный макет в надутом

SHOULD_FYI_VIEW_BE_SHOWN=true

Максимальная "оценка в реальном времени", заданная TraceView, имеет 75 мс, когда есть только представление для изменения от GONE до VISIBLE, но 110 мс, когда нам нужно создать экземпляр inner_view.

Если дополнительный макет не завышен SHOULD_FYI_VIEW_BE_SHOWN=false

В этом случае максимальная оценка в реальном времени, заданная TraceView, имеет 102 мс для инфляции представления GONE по сравнению с 39 мс, когда просмотр завышен, t имеет представление GONE.

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

Вы можете найти тестовый проект на Gist

Ответ 2

Я думаю, вы изобретаете колесо. Для этого сценария уже существует инструмент в макетах xml для Android. Он называется ViewStub. Вы можете прочитать больше здесь: Загрузка ondemand

Ответ 3

Думаю, я просто случайно наткнулся на ответ на ваш вопрос о производительности.

Из Анимационные документы:

Для просмотра, которое исчезает, установите его видимость в GONE. Эта предотвращает захват представления из пространства макета и опускает его из макета , ускорение обработки.

Это означало бы, что производительность не будет скомпрометирована, если вы не установите android:visibility на что-либо еще, кроме GONE.