40 votes

Android - Tentative d'invocation de la méthode virtuelle 'void Android.view.View.getBoundsOnScreen(Android.graphics.Rect)' sur une référence objet nulle

J'ai un formulaire d'adresse simple comme celui-ci :

Java :

public class NewAddressActivity extends AppCompatActivity {

private TextInputLayout mStreetLayout;
private TextInputLayout mNumberLayout;
private TextInputLayout mNeighborhoodLayout;
private TextInputLayout mCityLayout;
private TextInputLayout mStateLayout;
private TextInputLayout mCepLayout;
private TextInputLayout mPhoneLayout;
private EditText mStreetText;
private EditText mNumberText;
private EditText mComplementText;
private EditText mNeighborhoodText;
private EditText mCityText;
private EditText mStateText;
private EditText mCepText;
private EditText mPhoneText;

private Address mAddressEditing;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_address);

    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    mStreetLayout = findViewById(R.id.street_layout);
    mNumberLayout = findViewById(R.id.number_layout);
    mNeighborhoodLayout = findViewById(R.id.neighborhood_layout);
    mCityLayout = findViewById(R.id.city_layout);
    mStateLayout = findViewById(R.id.state_layout);
    mCepLayout = findViewById(R.id.cep_layout);
    mPhoneLayout = findViewById(R.id.phone_layout);
    mStreetText = findViewById(R.id.street_text);
    mNumberText = findViewById(R.id.number_text);
    mComplementText = findViewById(R.id.complement_text);
    mNeighborhoodText = findViewById(R.id.neighborhood_text);
    mCityText = findViewById(R.id.city_text);
    mStateText = findViewById(R.id.state_text);
    mCepText = findViewById(R.id.cep_text);
    mPhoneText = findViewById(R.id.phone_text);

    mAddressEditing = getIntent().getParcelableExtra(AppConstants.ADDRESS_EXTRA);

    if (mAddressEditing != null) {
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        if (actionBar != null) {
            actionBar.setTitle(R.string.edit_address);
        }
        mStreetText.setText(mAddressEditing.getStreet());
        mNumberText.setText(mAddressEditing.getNumber());
        mComplementText.setText(mAddressEditing.getComplement());
        mNeighborhoodText.setText(mAddressEditing.getNeighborhood());
        mCityText.setText(mAddressEditing.getCity());
        mStateText.setText(mAddressEditing.getState());
        mCepText.setText(mAddressEditing.getCep());
        mPhoneText.setText(mAddressEditing.getPhone());
        mStreetText.setSelection(mAddressEditing.getStreet().length());
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_new_address, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
        case R.id.action_save:
            save();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

@SuppressLint("StaticFieldLeak")
private void save() {
    String street = mStreetText.getText().toString().trim();
    String number = mNumberText.getText().toString().trim();
    String complement = mComplementText.getText().toString().trim();
    String neighborhood = mNeighborhoodText.getText().toString().trim();
    String city = mCityText.getText().toString().trim();
    String state = mStateText.getText().toString().trim();
    String cep = mCepText.getText().toString().trim();
    String phone = mPhoneText.getText().toString().trim();

    boolean hasError = false;

    if (TextUtils.isEmpty(street)) {
        hasError = true;
        mStreetLayout.setErrorEnabled(true);
        mStreetLayout.setError(getString(R.string.fill_the_field));
    }
    if (TextUtils.isEmpty(number)) {
        hasError = true;
        mNumberLayout.setErrorEnabled(true);
        mNumberLayout.setError(getString(R.string.fill_the_field));
    }
    if (TextUtils.isEmpty(neighborhood)) {
        hasError = true;
        mNeighborhoodLayout.setErrorEnabled(true);
        mNeighborhoodLayout.setError(getString(R.string.fill_the_field));
    }
    if (TextUtils.isEmpty(city)) {
        hasError = true;
        mCityLayout.setErrorEnabled(true);
        mCityLayout.setError(getString(R.string.fill_the_field));
    }
    if (TextUtils.isEmpty(state)) {
        hasError = true;
        mStateLayout.setErrorEnabled(true);
        mStateLayout.setError(getString(R.string.fill_the_field));
    }
    if (TextUtils.isEmpty(cep)) {
        hasError = true;
        mCepLayout.setErrorEnabled(true);
        mCepLayout.setError(getString(R.string.fill_the_field));
    }
    if (TextUtils.isEmpty(phone)) {
        hasError = true;
        mPhoneLayout.setErrorEnabled(true);
        mPhoneLayout.setError(getString(R.string.fill_the_field));
    }

    if (hasError) {
        return;
    }

    final Address address = new Address();
    if (mAddressEditing != null) {
        mAddressEditing.setStreet(street);
        mAddressEditing.setNumber(number);
        mAddressEditing.setComplement(complement);
        mAddressEditing.setNeighborhood(neighborhood);
        mAddressEditing.setCity(city);
        mAddressEditing.setState(state);
        mAddressEditing.setCep(cep);
        mAddressEditing.setPhone(phone);
    } else {
        address.setStreet(street);
        address.setNumber(number);
        address.setComplement(complement);
        address.setNeighborhood(neighborhood);
        address.setCity(city);
        address.setState(state);
        address.setCep(cep);
        address.setPhone(phone);
    }

    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {
            if (mAddressEditing != null) {
                MainApplication.getInstance().getAddressDao().update(mAddressEditing);
            } else {
                MainApplication.getInstance().getAddressDao().insert(address);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            Toast.makeText(NewAddressActivity.this,
                    mAddressEditing != null ? R.string.address_edited_successfully :
                            R.string.address_created_successfully, Toast.LENGTH_SHORT).show();
            setResult(Activity.RESULT_OK);
            finish();
        }
    }.execute();
}
}

xml :

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.design.widget.TextInputLayout
        android:id="@+id/street_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent">

        <EditText
            android:id="@+id/street_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/street"
            android:imeOptions="actionNext"
            android:inputType="textCapSentences"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/number_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/street_layout">

        <EditText
            android:id="@+id/number_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/number"
            android:imeOptions="actionNext"
            android:inputType="textCapSentences"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/complement_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/number_layout">

        <EditText
            android:id="@+id/complement_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/complement"
            android:imeOptions="actionNext"
            android:inputType="textCapSentences"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/neighborhood_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/complement_layout">

        <EditText
            android:id="@+id/neighborhood_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/neighborhood"
            android:imeOptions="actionNext"
            android:inputType="textCapSentences"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/city_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/neighborhood_layout">

        <EditText
            android:id="@+id/city_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/city"
            android:imeOptions="actionNext"
            android:inputType="textCapSentences"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/state_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/city_layout">

        <EditText
            android:id="@+id/state_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/state"
            android:imeOptions="actionNext"
            android:inputType="textCapSentences"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/cep_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/state_layout">

        <EditText
            android:id="@+id/cep_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/cep"
            android:imeOptions="actionNext"
            android:inputType="number"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/phone_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toBottomOf="@id/cep_layout">

        <EditText
            android:id="@+id/phone_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/phone"
            android:imeOptions="actionDone"
            android:inputType="phone|textCapSentences"
            android:maxLines="1"
            android:singleLine="true" />
    </android.support.design.widget.TextInputLayout>
</android.support.constraint.ConstraintLayout>
</ScrollView>

Comment vous pouvez voir sur java, mAddressEditing est reçue de l'intention, quand elle n'est pas nulle, cela signifie que l'utilisateur veut modifier son adresse.

Tous les champs sont remplis comme prévu, mais lorsque je tape sur un texte à modifier pour changer sa valeur, le système se bloque...

Crash :

FATAL EXCEPTION: main 
Process: br.com.fornaro.armariovirtual, PID: 5540
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.getBoundsOnScreen(android.graphics.Rect)' on a null object reference at android.app.assist.AssistStructure$WindowNode.<init>(AssistStructure.java:484)
at android.app.assist.AssistStructure.<init>(AssistStructure.java:1908)
at android.app.ActivityThread.handleRequestAssistContextExtras(ActivityThread.java:3035)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1807)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Je n'ai aucune idée de la raison pour laquelle il se plante.

Étapes à reproduire : 1. Modifier une adresse à partir de l'écran précédent en passant l'objet Adresse comme paramètre sur l'intention. 2. Cliquez sur un texte à modifier pour changer sa valeur. 3. Crash !

54voto

Ray Li Points 658

Le problème est un bug connu d'Android. D'après les suggestions du Google Issue Tracker, le réglage de l'indice sur le TextInputEditText semble être à l'origine du plantage. Le fait de définir l'indice uniquement sur le TextInputLayout corrige le problème.

Ce problème ne se produit que SI l'indice est défini sur le EditText imbriqué imbriqué dans le TextInputLayout. J'ai résolu le problème en définissant l'indice sur l'élément TextInputLayout.

https://issuetracker.google.com/issues/62834931 Commentaire n° 28

41voto

Pemba Tamang Points 247

Définissez l'indice sur le TextInputLayout au lieu de l'EditText imbriqué. Il ne se plantera pas.

<android.support.design.widget.TextInputLayout
                    android:id="@+id/til1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Phone Number">
                    <EditText
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/login_phone"
                        android:inputType="number"
                        android:singleLine="true" />
                </android.support.design.widget.TextInputLayout>

38voto

Douglas Fornaro Points 1074

L'ajout de ce code sur chaque texte d'édition a résolu mon problème :

android:importantForAutofill="noExcludeDescendants"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X