Osmdroid -NullPointerException:尝试调用虚拟方法'boolean org.osmdroid.views.overlay.Overlay.onTouchEvent

Osmdroid -NullPointerException: Attempt to invoke virtual method 'boolean org.osmdroid.views.overlay.Overlay.onTouchEvent

我的应用程序有问题,其中包括 osmdroid。每次我尝试 运行 设备上的应用程序并触摸地图时,应用程序都会崩溃,并且出现此错误:

    2018-10-02 14:11:45.191 19645-19645/com.message_drop.messagedrop E/InputEventReceiver: Exception dispatching input event.
2018-10-02 14:11:45.191 19645-19645/com.message_drop.messagedrop E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
2018-10-02 14:11:45.196 19645-19645/com.message_drop.messagedrop E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean org.osmdroid.views.overlay.Overlay.onTouchEvent(android.view.MotionEvent, org.osmdroid.views.MapView)' on a null object reference
        at org.osmdroid.views.overlay.DefaultOverlayManager.onTouchEvent(DefaultOverlayManager.java:214)
        at org.osmdroid.views.MapView.dispatchTouchEvent(MapView.java:1050)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:552)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1959)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3530)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:505)
        at android.view.View.dispatchPointerEvent(View.java:12082)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5325)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5109)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4623)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4676)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4769)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4650)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4826)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4623)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4676)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4650)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4623)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7222)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7196)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7157)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7379)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:193)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:379)
        at android.os.Looper.loop(Looper.java:144)
        at android.app.ActivityThread.main(ActivityThread.java:7377)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
2018-10-02 14:11:45.196 19645-19645/com.message_drop.messagedrop D/AndroidRuntime: Shutting down VM
2018-10-02 14:11:45.201 19645-19645/com.message_drop.messagedrop E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.message_drop.messagedrop, PID: 19645
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean org.osmdroid.views.overlay.Overlay.onTouchEvent(android.view.MotionEvent, org.osmdroid.views.MapView)' on a null object reference
        at org.osmdroid.views.overlay.DefaultOverlayManager.onTouchEvent(DefaultOverlayManager.java:214)
        at org.osmdroid.views.MapView.dispatchTouchEvent(MapView.java:1050)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2981)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2611)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:552)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1959)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3530)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:505)
        at android.view.View.dispatchPointerEvent(View.java:12082)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5325)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5109)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4623)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4676)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4769)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4650)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4826)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4623)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4676)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4642)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4650)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4623)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7222)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7196)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7157)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7379)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:193)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:379)
        at android.os.Looper.loop(Looper.java:144)
        at android.app.ActivityThread.main(ActivityThread.java:7377)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)

我不知道如何处理这个错误,希望有人能帮助我。我已经在互联网上寻找解决方案,但没有找到任何解决方案。 如果您需要更多代码,请告诉我。

这是我的 MainActivity.java:

public class MainActivity extends AppCompatActivity implements LocationListener, View.OnClickListener {

    MapView mapView;
    MyLocationNewOverlay myLocationOverlay;
    private static final String TAG = "MainActivity";

    String content = "a";
    String author = "b";
    Double latitude = 53.2;
    Double longitude = 11.5;
    private ItemizedIconOverlay<OverlayItem> messagesOverlay;
    private List<OverlayItem> items = new ArrayList<>();
    private long totalNumberChilds;



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

        //set up the mapView and show the MyLocationOverlay
        mapView = findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapView.setMultiTouchControls(true);
        mapView.getController().setZoom(5);
        myLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(getApplicationContext()), mapView);
        myLocationOverlay.enableMyLocation();
        mapView.getOverlays().add(messagesOverlay);
        mapView.getOverlays().add(myLocationOverlay);
        GeoPoint point = this.myLocationOverlay.getMyLocation();
        if(point==null){
            return;
        } else {
            mapView.getController().animateTo(point);
        }

        //initialize the Overlay for the Messages
        messagesOverlay = new ItemizedIconOverlay<OverlayItem>(items, getResources().getDrawable(R.drawable.briefumschlag), null, this);

        //messagesOverlay.addItem(new OverlayItem(author, "", new GeoPoint(latitude, longitude)));

        //declare the database variables in onCreate
        //NOTE: Unless you are signed in, this will not be useable.
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference("message");

        // Read from the database
        myRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                // This method is called once with the initial value and again
                // whenever data at this location is updated.
                messagesOverlay.removeAllItems();
                Toast.makeText(MainActivity.this, "yesss", Toast.LENGTH_LONG).show();
                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    //Message message = new Message();
                    //String author1 = ds.child("messageAuthor").getValue(String.class);
                    /*String content1 = ds.child("messageContent").getValue(String.class);
                    Double latitude1 = ds.child("messageLatitude").getValue(Double.class);
                    Double longitude1 = ds.child("messageLongitude").getValue(Double.class);
                    messagesOverlay.addItem(new OverlayItem("by" + author1, "", new GeoPoint(latitude1, longitude1)));*/

                }

            }

            @Override
            public void onCancelled(DatabaseError error) {
                // Failed to read value
            }
        });
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.testButton) {
            addMessage();
        }
    }

    public void addMessage() {
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference("message");

        String id = myRef.push().getKey();

        Message message = new Message(author, content, latitude, longitude);

        myRef.child(id).setValue(message);

        Toast.makeText(this, "Message added", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onLocationChanged(Location location) {
        GeoPoint point = new GeoPoint(location);
        if(point==null){
            return;
        } else {
            mapView.getController().animateTo(point);
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

}

我的LoginActivity.java:

public class LoginActivity extends AppCompatActivity implements View.OnClickListener {

    private FirebaseAuth mAuth;
    FirebaseAuth.AuthStateListener mAuthListener;

    private EditText tfEmail, tfPassword;
    private static final String TAG = "LoginActivity";

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

        tfEmail = findViewById(R.id.tfEmail);
        tfPassword = findViewById(R.id.tfPassword);

        mAuth = FirebaseAuth.getInstance();

        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    //User is signed in
                    Log.d(TAG, "onAuthStateChanged:signed_in" + user.getUid());
                    Toast.makeText(LoginActivity.this, "Successfully signed in with:" + user.getEmail(),
                            Toast.LENGTH_SHORT).show();
                } else {
                    //User is signed out
                    Log.d(TAG, "onAuthStateChanged:signed_out");
                    Toast.makeText(LoginActivity.this, "Successfully signed out.", Toast.LENGTH_SHORT).show();
                }
            }
        };
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btnSignIn) {
            String email = tfEmail.getText().toString();
            String password = tfPassword.getText().toString();
            if (!email.equals("") && !password.equals("")) {
                mAuth.signInWithEmailAndPassword(email, password);
                Intent intent = new Intent(this, MainActivity.class);
                startActivity(intent);
            } else {
                Toast.makeText(this, "Please fill in all fields!", Toast.LENGTH_SHORT).show();
            }
        } else if (v.getId() == R.id.btnSignOut) {
            mAuth.signOut();
            Toast.makeText(this, "Signing Out...", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        // Check if user is signed in (non-null) and update UI accordingly.
        mAuth.addAuthStateListener(mAuthListener);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mAuthListener != null) {
            mAuth.removeAuthStateListener(mAuthListener);
        }
    }


}

我的Message.java:

public class Message {

    String messageAuthor;
    String messageContent;
    Double messageLatitude;
    Double messageLongitude;

    public Message() {

    }

    public Message(String messageAuthor, String messageContent, Double messageLatitude, Double messageLongitude) {
        this.messageAuthor = messageAuthor;
        this.messageContent = messageContent;
        this.messageLatitude = messageLatitude;
        this.messageLongitude = messageLongitude;
    }

    public String getMessageAuthor() {
        return messageAuthor;
    }

    public String getMessageContent() {
        return messageContent;
    }

    public Double getMessageLatitude() {
        return messageLatitude;
    }

    public Double getMessageLongitude() {
        return messageLongitude;
    }

    public void setMessageAuthor(String messageAuthor) {
        this.messageAuthor = messageAuthor;
    }

    public void setMessageContent(String messageContent) {
        this.messageContent = messageContent;
    }

    public void setMessageLatitude(Double messageLatitude) {
        this.messageLatitude = messageLatitude;
    }

    public void setMessageLongitude(Double messageLongitude) {
        this.messageLongitude = messageLongitude;
    }
}

我的activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android">

        <org.osmdroid.views.MapView
            android:id="@+id/mapview"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </org.osmdroid.views.MapView>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:id="@+id/testButton"
            android:text="add"
            />

    </FrameLayout>

和我的 activity_login.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/tfEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"
        android:hint="Email"/>

    <EditText
        android:id="@+id/tfPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
        android:hint="Password"/>

    <Button
        android:id="@+id/btnSignIn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Sign In"
        android:onClick="onClick"/>

    <Button
        android:id="@+id/btnSignOut"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Sign Out"
        android:onClick="onClick"/>

</LinearLayout>

我应该提到的一件事是,在我添加 LoginActivity 之前 class 地图工作得很好。

仔细检查你的 onCreate 方法:

super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //set up the mapView and show the MyLocationOverlay
    mapView = findViewById(R.id.mapview);
    //... shortened ...
    mapView.getOverlays().add(messagesOverlay); // <== here you are adding null, the messagesOevrlay variable is not yet initialized
    mapView.getOverlays().add(myLocationOverlay);

    //..shortened...


    // here you are creating the instance
    messagesOverlay = new ItemizedIconOverlay<OverlayItem>(items, getResources().getDrawable(R.drawable.briefumschlag), null, this);

您应该在调用 getOverlays().add() 之前移动创建实例的行,或者将 getOverlays().add(messagesOverlay) 向下移动。