Является ли привязка просмотра по умолчанию потокобезопасной?

#android #android-viewbinding

Вопрос:

 abstract class CoreActivity<VB : ViewBinding> : ScopeActivity(),
    CoroutineScope,
    LifecycleObserver {

    ...
    private lateinit var binding: VB
    ...

    /**
     * Function to access ViewBinding object within Activity.
     * */
    protected fun binding(func: VB.() -> Unit) = launch { binding.run(func) }
}
 

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

Затем я сделал protected fun binding(func: VB.() -> Unit) = launch { binding.run(func) } так, чтобы его дочерние элементы могли безопасно получать доступ к содержимому привязки представления в основном потоке.

Один из моих коллег спросил меня, что он хотел бы получить доступ к представлениям в более однострочном формате. например binding.textview.text = "Text"

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

Итак, к вопросу о том, является ли привязка просмотра по умолчанию потокобезопасной?

Образец сгенерированного кода класса привязки представлений:

 public final class ActivitySplashBinding implements ViewBinding {
  @NonNull
  private final LinearLayout rootView;

  private ActivitySplashBinding(@NonNull LinearLayout rootView) {
    this.rootView = rootView;
  }

  @Override
  @NonNull
  public LinearLayout getRoot() {
    return rootView;
  }

  @NonNull
  public static ActivitySplashBinding inflate(@NonNull LayoutInflater inflater) {
    return inflate(inflater, null, false);
  }

  @NonNull
  public static ActivitySplashBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup parent, boolean attachToParent) {
    View root = inflater.inflate(R.layout.activity_splash, parent, false);
    if (attachToParent) {
      parent.addView(root);
    }
    return bind(root);
  }

  @NonNull
  public static ActivitySplashBinding bind(@NonNull View rootView) {
    if (rootView == null) {
      throw new NullPointerException("rootView");
    }

    return new ActivitySplashBinding((LinearLayout) rootView);
  }
}
 

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

Комментарии:

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

2. Также вы можете сделать binding as protected не закрытым, чтобы он был доступен, так как binding.textview.text = "Text" в этом вся идея расширения(создание базовых компонентов) и изменение его видимости не имеет ничего общего с безопасностью потоков.

3. «вы можете получить доступ к элементу пользовательского интерфейса только из основного потока, если вы сделаете это в каком-либо другом потоке, вы сразу же получите исключение» На самом деле это причина, по которой я создал функцию binding {} и ограничил видимость binding закрытым, чтобы они всегда имели доступ к привязке просмотра в основном потоке. В прошлом были случаи, когда кто-то обращался к привязке представления в другом потоке, и она была выпущена в производство.