Полезно ли вызывать findViewById каждый раз в жизненном цикле активности, когда это требуется?

Всякий раз, когда нам нужна ссылка на виджет, мы используем findByViewById.

Когда мы ссылаемся на виджет много времени в коде того же класса Activity, мы можем следовать любому из подходов:

  • Вызывать findViewById каждый раз в жизненном цикле активности.
  • Получите его в первый раз, сохраните ссылку как переменную частного экземпляра класса Activity.

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

EDIT: если мы перейдем к новой активности с A до B, мы не закончим A, так как мы хотим открыть A при нажатии. В этом сценарии как подойти к проблеме выше? Пожалуйста, помогите.

Ответ 1

Оба подхода имеют свои риски. В общем, вы должны называть findViewById() меньше времени, которое вы можете, с другой стороны, сохранение ссылки в классе Activity может привести к утечке памяти. Это зависит от того, что вы хотите делать, сколько раз вы его называете и основываясь на этом, выберите один из подходов. Для этого вам нужно проанализировать свой код, и если вы не знаете, что лучше, попробуйте оба и выберите "менее плохо", но, как правило, первый подход хуже второго, потому что вы знаете, всегда нужно найти через ВСЕ элементы, которые вы определили id.

Ответ 2

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

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

Ответ 3

Вторая возможность, безусловно, лучше.

findViewById выполняет итерацию во всей иерархии представления, что, конечно, стоит гораздо больше времени, чем ссылка.

Dianne Hackborn (разработчик Android) подробно рассказал о теме: https://groups.google.com/forum/#!topic/android-developers/_22Z90dshoM

Ответ 4

Доступ к переменной-члену всегда быстрее, чем любой вызов функции. Используемое пространство для этой переменной несущественно. Кстати: код выглядит намного чище!

Ответ 5

Вы должны решить это в соответствии с вашей целью. Удержание объекта для ваших просмотров происходит быстрее, чем получение вашего представления с помощью метода активности. Но это также означает, что вы используете память для справки, и это может вызвать утечку памяти.

Ответ 6

Возможно, я ошибаюсь, так как я новичок в Android, но я предпочитаю хранить переменную; это меньше кодирования для записи.

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

Доступ 1:

public Integer getTag(){
       FrameLayout frame1 = (FrameLayout) findViewById(R.id.frame_1);
       LinearLayout linear3 = (LinearLayout) frame1.findViewById(R.id.linear_3);
       ImageView imgView = (ImageView) linear3.findViewById(R.id.myImg);
       return Integer.valueOf( imgView.getTag().ToString());
}

Доступ 2:

 private ImageView myImageView;
 @Override
 public void onCreate( Bundle savedInstanceState){
       //set access to variable
 }   

 public Integer getTag(){
       //return Integer.valueOf( myImageView.getTag().ToString());
       //can be written
       Integer mTag = Integer.valueOf(myImageView.getTag().ToString());
       return mTag;
 }