Android 'java.lang.NullPointerException error' [дублировать]

Исходя из патча, с которым связан pjcunningham, поскольку wtforms еще не выпустил это обновление, я пошел вперед и создал свою собственную monkeypatch:

import wtforms_sqlalchemy.fields as f                                                                                                                                                                                                                                                                    
def get_pk_from_identity(obj):
    cls, key = f.identity_key(instance=obj)[:2]
    return ':'.join(f.text_type(x) for x in key)                             
f.get_pk_from_identity = get_pk_from_identity

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

2
задан tmlh 18 September 2013 в 20:43
поделиться

4 ответа

Вы не можете инициализировать View за пределами метода, подобного этому

CheckBox cb1 = (CheckBox) findViewById(R.id.cb1);
CheckBox cb2 = (CheckBox) findViewById(R.id.cb2);

, поскольку это будет означать, что эти строки работают до onCreate(), что приводит к тому, что эти переменные являются null и бросьте NPE при попытке вызвать методы для этих переменных. Это происходит потому, что вы вызываете setContentView(R.layout.your_layout) внутри onCreate() и ваш Views «живой» внутри этого layout. Это означает, что они не могут быть инициализированы до тех пор, пока ваш layout не будет inflated, вызвав setContentView(). Вы должны вызвать setContentView(), прежде чем пытаться инициализировать свой Views.

Что некоторые люди могут сделать, это создать отдельную функцию, которая инициализирует эти переменные сразу после вызова setContentView(). Что-то вроде этого

public class MyActivity
    // declare your Views so they are global to the class
    TextView tv;
   // more views
    @Override
    public void onCreat(stuff)
    {
       // super call
       setContentView(R.layout.my_layout);
       init();

, затем в вашей функции init() инициализируйте все Views, которые вы объявили

private void init()
{
     tv = (TextView) findViewById(R.id.myTextView);
     // more initializations
}

, но вы можете просто инициализировать их в onCreate() , onResume() или где бы то ни было, если это после setContentView() Объявление и инициализация их таким образом гарантирует, что все они доступны для других функций, слушателей, внутренних классов и т. д. из Activity. И если у вас много Views, это может немного уменьшить «беспорядок».

7
ответ дан codeMagic 24 August 2018 в 19:09
поделиться

Когда вы перемещаете объявления в начало класса, вы меняете локальные переменные на поля. Эти поля инициализируются при создании экземпляра, что означает, что они инициализируются «прямо перед», когда выполняется конструктор.

Теперь вы не можете вызывать методы экземпляра (например, findViewById) до завершения неявного вызова super().

Переместите их в конструктор, и все должно получиться.

0
ответ дан Norwæ 24 August 2018 в 19:09
поделиться

findViewById - это метод, который может быть запущен из активности (или любой группы представлений) после того, как представление было завышено. Чтобы раздуть вид уровня активности, вы обычно вызываете setContentView.

Поскольку setContentView еще не вызван, к действию не добавляются представления.

Вот как это сделать

public class MyClass extends Activity implements View.OnClickListener {


        CheckBox cb1;
        CheckBox cb2;

        public void onCreate(Bundle sis) {
            super.onCreate(sis);
            setContentView(R.layout.whatever);

            cb1 = (CheckBox) findViewById(R.id.cb1);
            cb2 = (CheckBox) findViewById(R.id.cb2);
        }

        public void checkboth(View view) {

            cb1.setchecked(true);   
            cb2.setchecked(true);

        }

        @Override
        public void onClick(View v) {
        }
    }
2
ответ дан Selecsosi 24 August 2018 в 19:09
поделиться

Вы не можете вызывать метод (findViewById) здесь и ожидать непустого значения. Представления создаются только в андроиде после вызова setContentView (R.layout.my_layout). Что вам нужно сделать, так это:

public class MyClass extends Activity implements View.OnClickListener {

CheckBox cb1 = null;
CheckBox cb2 = null;

//leaving out most code like onCreate. Just pretend it's there.
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate();
    setContentView(R.layout.my_layout);
    cb1 = (CheckBox) findViewById(R.id.cb1);
    cb2 = (CheckBox) findViewById(R.id.cb2);   
}

public void checkboth(View view) {            

    cb1.setchecked(true);
    cb2.setchecked(true);

}

@Override
public void onClick(View v) {
}
}
1
ответ дан tim.paetz 24 August 2018 в 19:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: