Как решить эту проблему Attempt to invoke virtual method on a null object reference

Я получаю эту ошибку во время запуска моего приложения. Я не могу понять, что мне делать. Вот мой файл MainActivity.java:

package com.example.axelreader;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {
    StringBuilder sb = new StringBuilder();
    TextView tvText;
    private SensorManager sensorManager;
    SensorEventListener axelListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            switch (event.sensor.getType()){
                case Sensor.TYPE_ACCELEROMETER:
                    for (int i = 0; i < 3; i++) {
                        valuesAccel[i] = event.values[i];
                        valuesAccelGravity[i] = (float) (0.1 * event.values[i] + 0.9 * valuesAccelGravity[i]);
                        valuesAccelMotion[i] = event.values[i]
                                - valuesAccelGravity[i];
                    }
                    break;
                case Sensor.TYPE_LINEAR_ACCELERATION:
                    for (int i = 0; i < 3; i++) {
                        valuesLinAccel[i] = event.values[i];
                    }
                    break;
                case Sensor.TYPE_GRAVITY:
                    for (int i = 0; i < 3; i++) {
                        valuesGravity[i] = event.values[i];
                    }
                    break;
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }
    };
    Sensor axel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvText = (TextView) findViewById(R.id.tvText);
        axel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

    }
    protected void onResume(){
        super.onResume();
        sensorManager.registerListener(axelListener, axel, SensorManager.SENSOR_DELAY_NORMAL);

        Timer timer = new Timer();
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    showInfo();
                }
            };
        }
    String format(float values[]){
        return String.format("%1$.1f\t\t%2$.1f\t\t%3$.1f", values[0], values[1],
                values[2]);
    }
    void showInfo(){
        sb.setLength(0);
        sb.append("Accelerometer: " + format(valuesAccel))
                .append("\n\nAccel motion: " + format(valuesAccelMotion))
                .append("\nAccel gravity : " + format(valuesAccelGravity))
                .append("\n\nLin accel : " + format(valuesLinAccel))
                .append("\nGravity : " + format(valuesGravity));
        tvText.setText(sb);
    }
    float[] valuesAccel = new float[3];
    float[] valuesAccelMotion = new float[3];
    float[] valuesAccelGravity = new float[3];
    float[] valuesLinAccel = new float[3];
    float[] valuesGravity = new float[3];

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text"
        tools:layout_editor_absoluteX="132dp"
        tools:layout_editor_absoluteY="354dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

И вот лог

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.axelreader, PID: 12888
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.axelreader/com.example.axelreader.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Sensor android.hardware.SensorManager.getDefaultSensor(int)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3121)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3264)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1955)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7091)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Sensor android.hardware.SensorManager.getDefaultSensor(int)' on a null object reference
        at com.example.axelreader.MainActivity.onCreate(MainActivity.java:55)
        at android.app.Activity.performCreate(Activity.java:7327)
        at android.app.Activity.performCreate(Activity.java:7318)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3101)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3264) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1955) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7091) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975) 

Ответы (1 шт):

Автор решения: Alex_Skvortsov

Добавьте в onCreate

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    ...
}

Пояснение:

строка private SensorManager sensorManager; не задает переменной sensorManager никакого значения, а только объявляет существование такой переменной. Указанное выше исправление задаст переменной значение (инициализирует) и теперь к sensorManager можно будет обращаться.

На будущее, как распознавать и исправлять подобные ошибки:

В logcat Вам выведено такое сообщение:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Sensor android.hardware.SensorManager.getDefaultSensor(int)' on a null object reference

Что отсюда можно извлечь:

  1. Была попытка вызвать метод getDefaultSensor (Attempt to invoke virtual method)
  2. Эта попытка была неудачной, потому что вызов происходил на неинициализированном объекте (null object reference)

У Вас вызов происходит только в одном месте:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tvText = (TextView) findViewById(R.id.tvText);
    axel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//здесь
}

При этом нигде в коде вы не присваиваете значение sensorManager, то есть у Вас нет строки вида sensorManager = ...;.

Отсюда решение:

Добавить инициализацию вида sensorManager = ...; выше axel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

Как это сделать?

Гуглим по запросу android sensormanager.

Первая же ссылка - документация.

Там есть пример кода

mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
→ Ссылка