【发布时间】:2021-08-24 22:09:38
【问题描述】:
我正在尝试从 firestore 获取实时数据并更新我的 android 应用程序中的类级别对象,但是当执行代码时应用程序崩溃并且当我检查它时显示以下错误:
2021-06-08 16:47:37.569 13632-13632/com.example.railtracker E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.railtracker, PID: 13632
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at com.example.railtracker.Acitivity.TrainLiveTrackViewActivity$1.onEvent(TrainLiveTrackViewActivity.java:80)
at com.example.railtracker.Acitivity.TrainLiveTrackViewActivity$1.onEvent(TrainLiveTrackViewActivity.java:69)
at com.google.firebase.firestore.DocumentReference.lambda$addSnapshotListenerInternal$2$DocumentReference(DocumentReference.java:504)
at com.google.firebase.firestore.-$$Lambda$DocumentReference$GF131yLOtm0PQYErAZvV1mYKmvw.onEvent(Unknown Source:6)
at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0$AsyncEventListener(AsyncEventListener.java:42)
at com.google.firebase.firestore.core.-$$Lambda$AsyncEventListener$DNkggu2LY54oguDvcp-QtRg6Sfg.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
我检查了将数据打印到终端并正确显示,但是当我尝试将其分配给变量时,应用程序崩溃了。请帮我解决这个问题。提前致谢。
我的代码:
package com.example.railtracker.Acitivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.IntentService;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import com.example.railtracker.Adapter.StopViewAdapter;
import com.example.railtracker.DTO.TrainDTO;
import com.example.railtracker.DTO.TrainInfoDTO;
import com.example.railtracker.R;
import com.example.railtracker.Util.FetchLocationIntentService;
import com.github.vipulasri.timelineview.TimelineView;
import com.google.android.gms.common.logging.Logger;
import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.snackbar.Snackbar;
import com.google.api.Logging;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
public class TrainLiveTrackViewActivity extends AppCompatActivity {
private static final String TAG= TrainLiveTrackViewActivity.class.getSimpleName();
private RecyclerView stopsView;
private Toolbar toolbar;
private TrainDTO train;
private LocationReceiver locationReceiver;
private Location lastLocation;
private String zipCode;
private TrainInfoDTO trainInfoDTO=new TrainInfoDTO();
private final String RESULT_DATA="RESULT_DATA";
private final String COLUMN="trains";
double sample;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_train_live_track_view);
setUpView();
locationReceiver=new LocationReceiver(new Handler());
loadRealTimeData();
}
private void loadRealTimeData()
{
try{
DocumentReference db= FirebaseFirestore.getInstance().collection(COLUMN).document( String.valueOf(train.getTrainId()));
db.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
if(error != null){
Log.e(TAG,error.getMessage());
error.printStackTrace();
}
if(value != null && value.exists()){
trainInfoDTO.setTrainId((int) value.get(getResources().getString(R.string.train_id)));
trainInfoDTO.setLat((double)value.get(getResources().getString(R.string.latitude)));
trainInfoDTO.setLon((double)value.get(getResources().getString(R.string.longitude)));
trainInfoDTO.setPassengerCount((int)value.get(getResources().getString(R.string.passenger_count)));
trainInfoDTO.setSeatingCapacity(train.getSeatingCapacity());
System.out.println(value.getData());
}
else{
showSnackbar(getResources().getString(R.string.no_train_data));
}
}
});
}catch (Exception e){
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
}
private void showSnackbar(String text){
View container=findViewById(android.R.id.content);
if(container != null){
Snackbar.make(container,text,Snackbar.LENGTH_LONG).show();
}
}
private void setUpView() {
toolbar=findViewById(R.id.ToolBarMain);
stopsView=findViewById(R.id.stops_rv);
Intent intent=getIntent();
train=(TrainDTO)intent.getSerializableExtra("train");
StopViewAdapter adapter=new StopViewAdapter(train.getCurrentShift().getStops(),this);
stopsView.setAdapter(adapter);
stopsView.setLayoutManager(new LinearLayoutManager(this));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(train.getName());
}
private void startIntentService()
{
Intent intent= new Intent(this, FetchLocationIntentService.class);
intent.putExtra("LocationReceiver",locationReceiver);
intent.putExtra("LastLocation",lastLocation);
startService(intent);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
private class LocationReceiver extends ResultReceiver {
/**
* Create a new ResultReceive to receive results. Your
* {@link #onReceiveResult} method will be called from the thread running
* <var>handler</var> if given, or from an arbitrary thread if null.
*
* @param handler
*/
public LocationReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
zipCode= resultData.getString(RESULT_DATA);
}
}
}
【问题讨论】:
-
我怀疑
value.get(getResources().getString(R.string.latitude))或value.get(getResources().getString(R.string.longitude))返回一个空引用。你检查过吗? -
是的,我检查过了,没关系,我也仔细检查了直接输入密钥,但结果相同。
-
没有完整的堆栈跟踪或任何值的日志,很难判断发生了什么。但我怀疑您发布的大部分代码都是无关紧要的......非常相关的将是堆栈跟踪,并且清楚地表明该堆栈跟踪中的任何行号在你的代码。
-
如果应用程序崩溃,会有一个堆栈跟踪。请在 logcat 上查找,并将其添加到您的问题中。请回复@AlexMamo
-
非常感谢您花时间我想通了。 firestore 中的文档有一个内部 Map,其中只有属性。所以我试图直接从文档中访问属性,这就是它抛出空指针异常的原因@AlexMamo
标签: java android firebase google-cloud-firestore real-time