Необъяснимая ошибка Nullpointer

Я разрабатываю приложение для Android, где пользователю сообщается, какое письмо нужно рисовать, а распознавание букв обрабатывается с помощью жестов. Я понятия не имею, почему это ломается. В eclipse ошибок не обнаружено, но logcat говорит об исключении nullpointer. Здесь мой код приложения:

public class MainActivity extends Activity implements OnGesturePerformedListener
{
 GestureLibrary mLibrary;
 Resources res;
 String [] letters;
 TextView tv = (TextView) findViewById(R.id.text);
 int i = 1;

 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
 if (!mLibrary.load())
 {
 finish();
 }

 res = getResources();
 letters = res.getStringArray(R.array.LetterToBeDrawn);
 tv.setText("Draw the letter: " + letters[i]);

 GestureOverlayView gestures = (GestureOverlayView)findViewById(R.id.gestures);
 gestures.addOnGesturePerformedListener(this);
 }


 @Override
 public boolean onCreateOptionsMenu(Menu menu) 
 {
 // Inflate the menu; this adds items to the action bar if it is present.
 ***************().inflate(R.menu.main, menu);
 return true;
 }

 public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) 
 { 
 ArrayList<prediction> predictions = new ArrayList<prediction>(); //this methods asks to recognize the gesture against loaded gesture library
 predictions = mLibrary.recognize(gesture);

 // We want at least one prediction
 if (predictions.size() > 0)
 {
 Prediction prediction = predictions.get(0); //get the 1st prediction auto generated for you by Android
 // We want at least some confidence in the result
 if (prediction.score > 1.0 && prediction.name.equals(letters[i]))
 {
 // Show the spell
 Toast.makeText(MainActivity.this, prediction.name, Toast.LENGTH_SHORT).show();
 }
 }
 }
}
</prediction></prediction>

Мой xml:

<android.gesture.gestureoverlayview xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/gestures" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" android:fadeoffset="1000" android:gesturestroketype="multiple" tools:context=".MainActivity">

 </android.gesture.gestureoverlayview>

Логарифм:

04-30 14:36:45.716: D/AndroidRuntime(1558): Shutting down VM
04-30 14:36:45.716: W/dalvikvm(1558): threadid=1: thread exiting with uncaught exception (group=0xb2a27ba8)
04-30 14:36:45.776: E/AndroidRuntime(1558): FATAL EXCEPTION: main
04-30 14:36:45.776: E/AndroidRuntime(1558): Process: com.gmail.Sheridjohn.letterchecker, PID: 1558
04-30 14:36:45.776: E/AndroidRuntime(1558): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.gmail.Sheridjohn.letterchecker/com.gmail.Sheridjohn.letterchecker.MainActivity}: java.lang.NullPointerException
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.ActivityThread.access$800(ActivityThread.java:135)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.os.Handler.dispatchMessage(Handler.java:102)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.os.Looper.loop(Looper.java:136)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.ActivityThread.main(ActivityThread.java:5017)
04-30 14:36:45.776: E/AndroidRuntime(1558): at java.lang.reflect.Method.invokeNative(Native Method)
04-30 14:36:45.776: E/AndroidRuntime(1558): at java.lang.reflect.Method.invoke(Method.java:515)
04-30 14:36:45.776: E/AndroidRuntime(1558): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-30 14:36:45.776: E/AndroidRuntime(1558): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-30 14:36:45.776: E/AndroidRuntime(1558): at dalvik.system.NativeStart.main(Native Method)
04-30 14:36:45.776: E/AndroidRuntime(1558): Caused by: java.lang.NullPointerException
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.Activity.findViewById(Activity.java:1884)
04-30 14:36:45.776: E/AndroidRuntime(1558): at com.gmail.Sheridjohn.letterchecker.MainActivity.<init>(MainActivity.java:23)
04-30 14:36:45.776: E/AndroidRuntime(1558): at java.lang.Class.newInstanceImpl(Native Method)
04-30 14:36:45.776: E/AndroidRuntime(1558): at java.lang.Class.newInstance(Class.java:1208)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
04-30 14:36:45.776: E/AndroidRuntime(1558): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112)
04-30 14:36:45.776: E/AndroidRuntime(1558): ... 11 more
</init>
3 ответа

У тебя есть

TextView tv = (TextView) findViewById(R.id.text);

перед установкой макета в Activity. Ошибка инициализации tv равна нулю. Сначала необходимо настроить макет на активность, а затем инициализировать представления.

И когда у вас есть

tv.setText("Draw the letter: " + letters[i]);

вы вызываете setText, когда tv фактически null

http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/app/Activity.java#1884

Проводка источника по ссылке, предоставленной laalto. Благодаря ему я исправил свой пост

1877 /**
1878 * Finds a view that was identified by the id attribute from the XML that
1879 * was processed in {@link #onCreate}.
1880 *
1881 * @return The view if found or null otherwise.
1882 */
1883 public View findViewById(int id) {
1884 return getWindow().findViewById(id);
1885 }
1886

Ваша stacktrace указывает на причину, по которой она не была необъяснима, как вы опубликовали в заголовке

Причина: java.lang.NullPointerException 04-30 14: 36: 45.776: E/AndroidRuntime (1558): at android.app.Activity.findViewById(Activity.java:1884) 04-30 14: 36: 45.776: E/AndroidRuntime (1558): at com.gmail.Sheridjohn.letterchecker.MainActivity. (MainActivity.java:23)


Причина в том, что вы вызываете findViewById() перед onCreate() при инициализации переменных-членов. В вашей деятельности еще нет Window и findViewById() нуждается в нем.

Для справки, здесь источник платформы для строки кода, которая вызывает NPE: http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/app/Activity.java#1884 - getWindow() возвращает null там.

setContentView() данное другими ответами, работает, но не совсем верно. Если у вас было Window и было callind findViewById() до setContentView(), вместо возвращаемого NPE будет возвращен нуль.

Решение остается прежним: переместите инициализацию в onCreate() после setContentView().


Ваша активность вызывает findViewById перед setContentView. Переместить tv = (TextView) findViewById(R.id.text); в onCreate.

licensed under cc by-sa 3.0 with attribution.