AppCompat - Spinner не работает в RelativeLayout

Я получаю следующую ошибку (используя новейшую библиотеку поддержки v23.0 и сборку SDK 23):

Случай 1: Android 4.2.1

java.lang.NullPointerException
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:523)
at android.view.View.measure(View.java:15612)
at android.support.v7.internal.widget.ListViewCompat.measureHeightOfChildrenCompat(ListViewCompat.java:301)
at android.support.v7.widget.ListPopupWindow.buildDropDown(ListPopupWindow.java:1200)
at android.support.v7.widget.ListPopupWindow.show(ListPopupWindow.java:584)
at android.support.v7.widget.AppCompatSpinner$DropdownPopup.show(AppCompatSpinner.java:766)
at android.support.v7.widget.AppCompatSpinner.performClick(AppCompatSpinner.java:424)
at android.view.View$PerformClick.run(View.java:17439)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5341)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:929)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
at dalvik.system.NativeStart.main(Native Method)

Случай 2: Android 4.3

java.lang.NullPointerException
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:578)
at android.view.View.measure(View.java:16831)
at android.support.v7.internal.widget.ListViewCompat.measureHeightOfChildrenCompat(ListViewCompat.java:301)
at android.support.v7.widget.ListPopupWindow.buildDropDown(ListPopupWindow.java:1200)
at android.support.v7.widget.ListPopupWindow.show(ListPopupWindow.java:584)
at android.support.v7.widget.AppCompatSpinner$DropdownPopup.show(AppCompatSpinner.java:766)
at android.support.v7.widget.AppCompatSpinner.performClick(AppCompatSpinner.java:424)
at android.view.View$PerformClick.run(View.java:18786)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)

На самом деле я не знаю, с чего начать поиск. Я получаю эту ошибку из-за сбоев и не могу воспроизвести ее на своем телефоне. И я не знаю, откуда это на самом деле.

Я искал свой код, и у меня нет Spinner, непосредственно вложенного в какой-либо RelativeLayout...

У кого-нибудь есть намек, что может вызвать эту проблему?

Внесенные мною изменения в код

В основном я обновлял библиотеку поддержки и собирал SDK версии 22 до версии 23. И у меня никогда не было такой проблемы раньше...

Причина ошибки, продемонстрированная на основе ошибки в Android 4.2.1:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.1_r1.2/android/widget/RelativeLayout.java#RelativeLayout

Здесь, в строке 523... Это то, что я получаю из отчета об ошибке, который я получаю...

523 if (mLayoutParams.height >= 0) {
524 height = Math.max(height, mLayoutParams.height);
525 }

В андроиде 4.3 на самом деле та же проблема, mLayoutParams равно нулю...


comment
поддержка обновления 23.0.1 может быть его решением   -  person Dhaval Parmar    schedule 04.09.2015
comment
Я могу это сделать, но проблема не указана здесь: developer.android.com/ tools/support-library/index.html. Поэтому я не уверен, что проблема вызвана библиотекой поддержки...   -  person prom85    schedule 04.09.2015
comment
java.lang.NullPointerException   -  person Phantômaxx    schedule 04.09.2015
comment
@FrankN.Stein, что это значит?   -  person prom85    schedule 04.09.2015
comment
Опубликуйте код - там ошибка: вы ссылаетесь на нулевой объект.   -  person Phantômaxx    schedule 04.09.2015
comment
Код совершенно уверен, что не проблема, у меня тысячи запущенных установок и около 3 сбоев (конечно, я не уверен, поэтому каждый совет помогает) ... И я не могу воспроизвести его на своем телефоне, я могу открыть каждый счетчик в моем приложении, и ничего никогда не падает. И я получаю только выше краш-лога, не более того. Я просто не могу определить, откуда в моем коде появляется эта ошибка... поэтому я не могу опубликовать какой-то код, иначе я бы, конечно, уже сделал это...   -  person prom85    schedule 04.09.2015
comment
@prom85 я бы посмотрел исходный код RelativeLayout androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/. строка 523 относится к for (int i = 0; i < count; i++) . Также на каком устройстве происходит сбой   -  person Raghunandan    schedule 04.09.2015
comment
Я получил отчеты с 4.2.1, 4.2.2 и 4.3... И у меня есть устройство под управлением Android 5.0 без проблем...   -  person prom85    schedule 04.09.2015
comment
PS: это отличается от того, что вы опубликовали. Я также добавил основной код в свой вопрос и ссылку на исходный код RelativeLayout...   -  person prom85    schedule 04.09.2015
comment
PPS: Я также добавил исключение для Android 4.3 и лучше описал, к какой версии Android относятся исключения...   -  person prom85    schedule 04.09.2015


Ответы (4)


Я нашел причину.

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

convertView = mInflater.inflate(mLayoutRes, null);

Должно быть

convertView = mInflater.inflate(mLayoutRes, null, false);

если адаптер используется в Spinner...

person prom85    schedule 07.09.2015
comment
У меня была эта проблема, чтобы обновить мой проект Android 22 до 23, работающий на устройстве Android 17. Его решение сработало для меня. Спасибо. - person Douglas Nassif Roma Junior; 22.09.2015
comment
Мне также нужно было добавить группу просмотра вместо null. - person Geob-o-matic; 10.10.2015

Попробуйте использовать следующий код:

Activity_main.xml

    <RelativeLayout xmlns:androclass="http://schemas.android.com/apk/res/android"  
        xmlns:tools="http://schemas.android.com/tools"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent"  
        tools:context=".MainActivity" >  

        <Spinner  
            android:id="@+id/spinner1"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:layout_alignParentTop="true"  
            android:layout_centerHorizontal="true"  
            android:layout_marginTop="83dp" />  

    </RelativeLayout>  

Основная активность.java:

package com.example.spinner;  
import android.app.Activity;  
import android.os.Bundle;  
import android.view.Menu;  
import android.view.View;  
import android.widget.AdapterView;  
import android.widget.ArrayAdapter;  
import android.widget.Spinner;  
import android.widget.TextView;  
import android.widget.Toast;  

public class MainActivity extends Activity implements  
AdapterView.OnItemSelectedListener {  

    String[] country = { "India", "USA", "China", "Japan", "Other",  };  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        //Getting the instance of Spinner and applying OnItemSelectedListener on it  
        Spinner spin = (Spinner) findViewById(R.id.spinner1);  
        spin.setOnItemSelectedListener(this);  


        ArrayAdapter aa = new ArrayAdapter(this,android.R.layout.simple_spinner_item,country);  
        aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);  

        spin.setAdapter(aa);  
    }  



    @Override  
    public void onItemSelected(AdapterView<?> arg0, View arg1, int position,long id) {  
        Toast.makeText(getApplicationContext(),country[position] ,Toast.LENGTH_LONG).show();  
    }  

    @Override  
    public void onNothingSelected(AdapterView<?> arg0) {  
        // TODO Auto-generated method stub  

    }  

    @Override  
    public boolean onCreateOptionsMenu(Menu menu) {  
        // Inflate the menu; this adds items to the action bar if it is present.  
        getMenuInflater().inflate(R.menu.activity_main, menu);  
        return true;  
    }  
}  
person Vinay Pandravada    schedule 04.09.2015
comment
Не могу воспроизвести баг. Он есть только у некоторых устройств. И мое приложение уже год работает без проблем, так что либо я добавил ошибку, либо она есть в новой библиотеке поддержки... - person prom85; 04.09.2015
comment
Итак, приложение в настоящее время работает на некоторых устройствах ?? - person Vinay Pandravada; 04.09.2015
comment
В яблочко. На моем устройстве я без проблем могу использовать каждый спиннер - person prom85; 04.09.2015
comment
Я не знаю, работает ли это, но попробуйте добавить setContentView(R.layout.your_layout_content); в метод onCreate перед инициализацией его представлений. - person Vinay Pandravada; 04.09.2015

Вы поймаете исключение, если раздуете макет, который имеет только представление (без ViewGroup). Пример android:layout/simple_spinner_dropdown_item имеет только CheckedTextView:

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/dropdownListPreferredItemHeight"
    android:ellipsize="marquee"/>

Вы можете исправить это, добавив ViewGroup в макет представления вашего адаптера:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <include layout="@android:layout/simple_spinner_dropdown_item"/>
</LinearLayout>
person sondt87    schedule 16.09.2015

Решение @prom85 у меня не сработало, пока я не передал parent ViewGroup вместо null:

convertView = mInflater.inflate(mLayoutRes, parent, false);
person M.Sameer    schedule 10.10.2015
comment
обычно родитель необходим только в том случае, если вы хотите использовать его тему, поэтому полезно использовать родителя, когда это возможно... - person prom85; 10.10.2015