如何解决空引用错误?我是新来的[重复]
Posted
技术标签:
【中文标题】如何解决空引用错误?我是新来的[重复]【英文标题】:How to solve null references error? Im new at this [duplicate] 【发布时间】:2020-05-20 03:36:15 【问题描述】:它说我的 getOutletId() 是空引用,我认为我已经声明了。 所以基本上这是一个预订步骤 4。第一步,用户需要从 Firestore 中选择出口并选择哪个分支,我已经包含到 setOutlet id。然后第二步将显示工作人员。我从firestore获得的所有信息除了Id,我都是手动完成的。 有人可以帮我解决这个问题吗?
这是我在预订步骤 1 片段中设置出口 id 的地方
private void loadBranchOfCity(String cityName)
dialog.show();
Common.city = cityName;
branchRef = FirebaseFirestore.getInstance()
.collection("AllPlace")
.document(cityName)
.collection("Branch");
branchRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>()
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task)
List<Outlet> list = new ArrayList<>();
if (task.isSuccessful())
for(QueryDocumentSnapshot documentSnapshot:task.getResult())
Outlet outlet = documentSnapshot.toObject(Outlet.class);
outlet.setOutletId(documentSnapshot.getId());
list.add(outlet);
iBranchLoadListener.onBranchLoadSuccess(list);
).addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
iBranchLoadListener.onBranchLoadFailed(e.getMessage());
);
这是我开始显示 outletId 的预订活动
@OnClick(R.id.btn_next_step)
void nextClick()
if (Common.step < 3 || Common.step == 0)
Common.step++; //increase
if (Common.step == 1) //After choose outlet
if(Common.currentOutlet != null)
loadStaffByOutlet(Common.currentOutlet.getOutletId());
else if(Common.step == 2) //pick time slot
if(Common.currentStaff != null)
loadTimeSlotOfStaff(Common.currentStaff.getStaffId());
else if(Common.step == 3) //Confirm
if(Common.currentTimeSlot != -1)
confirmBooking();
viewPager.setCurrentItem(Common.step);
private void confirmBooking()
//Send broadcast to fragment step four
Intent intent = new Intent (Common.KEY_CONFIRM_BOOKING);
localBroadcastManager.sendBroadcast(intent);
private void loadTimeSlotOfStaff(String staffId)
//Send local broadcast to fragment step 3
Intent intent = new Intent (Common.KEY_DISPLAY_TIME_SLOT);
localBroadcastManager.sendBroadcast(intent);
private void loadStaffByOutlet(String outletId)
dialog.show();
//Select all staff of Outlet
// /AllPlace/Melaka/Branch/RCgub6eOcf2c0s06Soyb/Staff
if (!TextUtils.isEmpty(Common.city))
staffRef = FirebaseFirestore.getInstance()
.collection("AllPlace")
.document(Common.city)
.collection("Branch")
.document(outletId)
.collection("Staff");
staffRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>()
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task)
ArrayList<Staff> staffs = new ArrayList<>();
for(QueryDocumentSnapshot staffsnapshot:task.getResult())
Staff staff = staffsnapshot.toObject(Staff.class);
staff.setPassword(""); //Remove password because this is client app
staff.setStaffId(staffsnapshot.getId());//get id of staff
staffs.add(staff);
//Send Broadcast to BookingStep2Fragment to load Recycler
Intent intent = new Intent(Common.KEY_STAFF_LOAD_DONE);
intent.putParcelableArrayListExtra(Common.KEY_STAFF_LOAD_DONE,staffs);
localBroadcastManager.sendBroadcast(intent);
dialog.dismiss();
).addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
dialog.dismiss();
);
这是我的日志
进程:com.example.CarServiceBooking,PID:12259 java.lang.NullPointerException:尝试调用虚拟方法'java.lang.String com.example.CarServiceBooking.Model.Outlet.getOutletId()' 为空 对象引用 在 com.example.CarServiceBooking.Fragment.BookingStep4Fragment$3$2.onSuccess(BookingStep4Fragment.java:216) 在 com.example.CarServiceBooking.Fragment.BookingStep4Fragment$3$2.onSuccess(BookingStep4Fragment.java:199) 在 com.google.android.gms.tasks.zzn.run(未知来源) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:135) 在 android.app.ActivityThread.main(ActivityThread.java:5254) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
这是我的普通课
public class Common
public static final String KEY_ENABLE_BUTTON_NEXT = "ENABLE_BUTTON_NEXT";
public static final String KEY_OUTLET_STORE = "OUTLET_SAVE";
public static final String KEY_STAFF_LOAD_DONE = "STAFF_LOAD_DONE";
public static final String KEY_DISPLAY_TIME_SLOT = "DISPLAY_TIME_SLOT";
public static final String KEY_STEP = "STEP" ;
public static final String KEY_STAFF_SELECTED = "STAFF_SELECTED";
public static final Object DISABLE_TAG = "DISABLE";
public static final String KEY_TIME_SLOT = "TIME_SLOT";
public static final String KEY_CONFIRM_BOOKING = "CONFIRM_BOOKING";
public static final String IS_LOGIN = "IsLogin";
public static final String EVENT_URI_CACHE = "URI_EVENT_SAVE";
public static final String TITLE_KEY = "title";
public static final String CONTENT_KEY = "content";
private static final String LOGGED_KEY = "LOGGED";
public static User currentUser;
public static Outlet currentOutlet;
public static Staff currentStaff;
public static int step = 0; //init first step is 0
public static String city = "";
public static int currentTimeSlot = -1;
public static final int TIME_SLOT_TOTAL = 9;
public static Calendar bookingDate = Calendar.getInstance();
public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd_MM_yyyy"); //only use when need format key
public static BookingInformation currentBooking;
public static String currentBookingId = "";
这是我的 BookingStep4Fragment,logcat 说它是空引用
private void addToUserBooking(final BookingInformation bookingInformation)
resetStaticData();
getActivity().finish(); //close activity
Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();
//First, create new collection
CollectionReference userBooking = FirebaseFirestore.getInstance()
.collection("Users")
.document(Common.currentUser.getPhone())
.collection("Booking");
//Check if exist document in this collection
//Get Current Date
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE,0);
calendar.set(Calendar.HOUR_OF_DAY,0);
calendar.set(Calendar.MINUTE,0);
Timestamp toDayTimeStamp = new Timestamp(calendar.getTime());
userBooking
.whereGreaterThanOrEqualTo("timestamp",toDayTimeStamp)
.whereEqualTo("done",false)
.limit(1) //only take 1
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>()
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task)
if(task.isSuccessful())
//set data
userBooking.document()
.set(bookingInformation)
.addOnSuccessListener(new OnSuccessListener<Void>()
@Override
public void onSuccess(Void aVoid)
//Create Notification
MyNotification myNotification = new MyNotification();
myNotification.setUid(UUID.randomUUID().toString());
myNotification.setTitle("New Booking ");
myNotification.setContent("You have a new appointment for customer vehicle with "+Common.currentUser.getName());
myNotification.setRead(false); // we will only filter notification with 'read' is false on staff app
myNotification.setServerTimestamp(FieldValue.serverTimestamp());
//Submit notification to 'Notifications' collection of Staff
FirebaseFirestore.getInstance()
.collection("AllPlace")
.document(Common.city)
.collection("Branch")
.document(Common.currentOutlet.getOutletId())
.collection("Staff")
.document(Common.currentStaff.getStaffId())
.collection("Notifications") //if it not available, it will be create automatically
.document(myNotification.getUid()) //create unique key
.set(myNotification)
.addOnSuccessListener(new OnSuccessListener<Void>()
@Override
public void onSuccess(Void aVoid)
//First get Token base on staff id
FirebaseFirestore.getInstance()
.collection("Tokens")
.whereEqualTo("userPhone",Common.currentStaff.getUsername())
.limit(1)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>()
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task)
if (task.isSuccessful() && task.getResult().size() > 0)
MyToken myToken = new MyToken();
for (DocumentSnapshot tokenSnapShot : task.getResult())
myToken = tokenSnapShot.toObject(MyToken.class);
//Create data to send
FCMSendData sendRequest = new FCMSendData();
Map<String,String> dataSend = new HashMap<>();
dataSend.put(Common.TITLE_KEY, "New Booking");
dataSend.put(Common.CONTENT_KEY,"You have new booking from user "+Common.currentUser.getName());
sendRequest.setTo(myToken.getToken());
sendRequest.setData(dataSend);
compositeDisposable.add(ifcmApi.sendNotification(sendRequest)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<FCMResponse>()
@Override
public void accept(FCMResponse fcmResponse) throws Exception
dialog.dismiss();;
addToCalendar(Common.bookingDate,
Common.convertTimeSlotToString(Common.currentTimeSlot));
resetStaticData();
getActivity().finish(); //Close activity
Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();
, new Consumer<Throwable>()
@Override
public void accept(Throwable throwable) throws Exception
Log.d("NOTIFICATION_ERROR",throwable.getMessage());
addToCalendar(Common.bookingDate,
Common.convertTimeSlotToString(Common.currentTimeSlot));
resetStaticData();
getActivity().finish(); //Close activity
Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();
));
);
);
)
.addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
);
else
if(dialog.isShowing())
dialog.dismiss();
resetStaticData();
getActivity().finish(); //close activity
Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();
);
这是我的 Outlet 课程
public class Outlet implements Parcelable
private String name,address,website, phone,openHours,outletId;
public Outlet()
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getAddress()
return address;
public void setAddress(String address)
this.address = address;
public String getWebsite()
return website;
public void setWebsite(String website)
this.website = website;
public String getPhone()
return phone;
public void setPhone(String phone)
this.phone = phone;
public String getOpenHours()
return openHours;
public void setOpenHours(String openHours)
this.openHours = openHours;
public String getOutletId()
return outletId;
public void setOutletId(String outletId)
this.outletId = outletId;
protected Outlet(Parcel in)
name = in.readString();
address = in.readString();
website = in.readString();
phone = in.readString();
openHours = in.readString();
outletId = in.readString();
public static final Creator<Outlet> CREATOR = new Creator<Outlet>()
@Override
public Outlet createFromParcel(Parcel in)
return new Outlet(in);
@Override
public Outlet[] newArray(int size)
return new Outlet[size];
;
@Override
public int describeContents()
return 0;
@Override
public void writeToParcel(Parcel dest, int flags)
dest.writeString(name);
dest.writeString(address);
dest.writeString(website);
dest.writeString(phone);
dest.writeString(openHours);
dest.writeString(outletId);
【问题讨论】:
不,它没有。 【参考方案1】:Common 处出错。您将在此行中遇到错误。
public static User currentUser;
public static Outlet currentOutlet;
public static Staff currentStaff;
public static BookingInformation currentBooking;
因为,你没有初始化。你应该这样做;
public static User currentUser = new User ();
public static Outlet currentOutlet = new Outlet ();
public static Staff currentStaff = new Staff ();
public static BookingInformation currentBooking = new BookingInformation();
可能你会得到另一个错误。我显示了上面的代码,你没有为模型设置任何值。只有你从模型中获取值。你应该在从模型中获取数据之前在模型中设置数据。
【讨论】:
我已经在bookingstep1fragment的模型中设置了数据。这是我的代码(QueryDocumentSnapshot documentSnapshot:task.getResult()) Outlet outlet = documentSnapshot.toObject(Outlet.class); outlet.setOutletId(documentSnapshot.getId()); list.add(出口); 我认为你没有为outletId设置数据,或者如果你是从服务器收集数据并设置它的模型,那么你无法从服务器接收到outletId,所以模型中的outletId为空。跨度> 你在 outlet.setOutletId(documentSnapshot.getId()); 下面调试list.add(outlet) 这一行并检查出口数据我认为这里没有为 outletId 设置任何数据。 我已经编辑了问题。我已经为 outletId 设置了数据 你没有定义 Common.currentOutlet = outlet ; addOnCompleteListener 中的任何位置以上是关于如何解决空引用错误?我是新来的[重复]的主要内容,如果未能解决你的问题,请参考以下文章