web-dev-qa-db-fra.com

liaison de données - avertissement safeUnbox

après avoir mis à niveau AS Gradle version vers la version 2.3.0, la liaison de données rencontre un avertissement:

Avertissement: selectMap [index] est un champ mais vous devez le décocher pour exécuter selectMap [index]? @Android: couleur/blanc: @Android: couleur/transparent. Cela peut provoquer des NPE, de sorte que la liaison de données le déballe en toute sécurité. Vous pouvez modifier l'expression et envelopper explicitement selectMap [index] avec safeUnbox () pour empêcher l'avertissement.

selectMap est un ObservableMap, alors je recherche cet avertissement mais je n'ai que quelques discussions et je ne le répare pas

Android Studio 2.3.0-alpha1: liaison de données + unboxing int provoque des erreurs de compilation

Liaison de données - l'objet de données a la valeur null dans l'API 15-18

Je suis le chemin dans les liens, modifie selectMap[index] En safeUnbox(selectMap[index]) mais j'ai une erreur de syntaxe.

Donc, quelqu'un sait comment résoudre cet avertissement?


Edit: Voici le code du fichier xml

<?xml version="1.0" encoding="utf-8"?>
<data class="SupportCountryViewHolderBinding">

    <variable
        name="viewModel"
        type="com.goodarc.care_about.activity.account.support_country.SupportCountryHolderViewModel" />

    <variable
        name="dataSource"
        type="com.goodarc.care_about.module.assets_file.SupportCountry" />

    <variable
        name="selectMap"
        type="Android.databinding.ObservableMap&lt;Integer, Boolean&gt;" />

    <variable
        name="index"
        type="int" />
</data>

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@{selectMap[index] ? @Android:color/white : @Android:color/transparent}"
    Android:onClick="@{(v) -> viewModel.onItemSelectListener(selectMap, index)}"
    Android:orientation="vertical"
    Android:padding="20dp">

    <TextView
        style="@style/TitleLabel2"
        Android:layout_gravity="center_vertical|start"
        Android:text="@{dataSource.display}"
        Android:textColor="@{selectMap[index] ? @Android:color/black : @Android:color/white}"
        tools:text="Taiwan (+886)" />
</LinearLayout>

La construction est réussie, mais les avertissements sont sortis (ci-dessus).

45
Ivan

J'ai eu le même avertissement, dans mon cas, changer la déclaration de variable de Boolean type à boolean type résout le problème:

De:

<variable
        name="readOnly"
        type="Boolean" />

À:

<variable
        name="readOnly"
        type="boolean" />

Alors peut-être que vous pouvez essayer avec:

<variable
    name="selectMap"
    type="Android.databinding.ObservableMap&lt;Integer, boolean&gt;" />
34
Leandro D'Onofrio

Vous pouvez ajouter safeUnbox comme ceci:

Android:text="@{Double.toString(safeUnbox(product.listPrice))}"
23
dazza5000

w: avertissement: activé est un champ encadré, mais doit être débranché pour être exécuté Android: coché .

Cet avertissement vient parce que le champ activé peut être nul . Si vous prenez Boolean au lieu de boolean, alors Boolean peut être nul. Donc, cet avertissement vient. Que ce champ peut faire NullPointerException.

---------------- Cas 1 - Reliure à sens unique ----------------

<variable
    name="enabled"
    type="Boolean"/>

....

<Switch
    Android:checked="@{enabled}"
    />

Solution 1

<Switch
    Android:checked="@{safeUnbox(fieldName)}"
    />

Solution 2

Remplacez Boolean par un type primitif boolean. Pour qu'il ne soit jamais nul, valeur par défaut de boolean est false.

<variable
    name="enabled"
    type="boolean"/>

---------------- Cas 2 - Liaison bidirectionnelle ---------------- Lorsque vous avez une liaison bidirectionnelle, vous ne pouvez pas utiliser safeUnbox() manière, car safeUnbox() ne sera pas inversé .

<variable
    name="enabled"
    type="Boolean"/>

....

<Switch
    Android:checked="@={enabled}"
    />

Cela ne fonctionnera pas maintenant.

<Switch
    Android:checked="@{safeUnbox(fieldName)}"
    />

Solution 1

Remplacez Boolean par un type primitif boolean. Pour qu'il ne soit jamais nul, valeur par défaut de boolean est faux.

<variable
    name="enabled"
    type="boolean"/>

Solution 2

Un long chemin est de faire des adaptateurs de liaison inverse pour safeUnbox . Voir ici .

Quelle est la méthode safeUnbox ()?

safeUnbox() il suffit de vérifier la valeur NULL et de renvoyer une valeur non NULL. Vous pouvez voir ci-dessous les méthodes définies dans la bibliothèque de liaisons de données.

public static int safeUnbox(Java.lang.Integer boxed) {
    return boxed == null ? 0 : (int)boxed;
}
public static long safeUnbox(Java.lang.Long boxed) {
    return boxed == null ? 0L : (long)boxed;
}
public static short safeUnbox(Java.lang.Short boxed) {
    return boxed == null ? 0 : (short)boxed;
}
public static byte safeUnbox(Java.lang.Byte boxed) {
    return boxed == null ? 0 : (byte)boxed;
}
public static char safeUnbox(Java.lang.Character boxed) {
    return boxed == null ? '\u0000' : (char)boxed;
}
public static double safeUnbox(Java.lang.Double boxed) {
    return boxed == null ? 0.0 : (double)boxed;
}
public static float safeUnbox(Java.lang.Float boxed) {
    return boxed == null ? 0f : (float)boxed;
}
public static boolean safeUnbox(Java.lang.Boolean boxed) {
    return boxed == null ? false : (boolean)boxed;
}

J'ai expliqué à propos de booléen, cette solution est la même pour Integer, Double, Character etc.

9
Khemraj

Au lieu de ObservableField<T> vous devez utiliser une version spéciale pour les primitives:

  1. ObservableInt pour le int
  2. ObservableBoolean pour le boolean
  3. ObservableFloat pour le float
  4. ObservableChar pour le char
  5. ObservableLong pour le long
  6. ObservableByte pour le byte
  7. ObservableShort pour le short
7
Eugen Martynov

J'ai eu cet avertissement popup quand j'ai fait quelque chose comme:

 Android:visibility="@{viewmodel.isLoading ? View.INVISIBLE : View.VISIBLE}"

ajout de safeunbox comme ceci:

 Android:visibility="@{safeUnbox(viewmodel.isLoading) ? View.INVISIBLE : View.VISIBLE}"

enlevé l'avertissement après la reconstruction

5
JimmyFlash

Cela peut également apparaître chaque fois que vous utilisez un BindingAdapter personnalisé. Dans mon cas, je devais donc rendre le deuxième argument nullable, et l'avertissement a disparu.

@BindingAdapter("xyz")
fun xyzAdapter(view: View, value: Int?) {
  value?.let {
    //TODO
  }
}

Je n'utilise pas Java, mais si vous êtes sûr d'inclure @Nullable annotation et crée une condition nulle.

0
Juan Mendez