全局变量在android studio中返回null [重复]
Posted
技术标签:
【中文标题】全局变量在android studio中返回null [重复]【英文标题】:Global variable is returning null in android studio [duplicate] 【发布时间】:2021-07-28 09:51:03 【问题描述】:我正在从 Firestore 中检索医院数据。我想将检索到的数据保持为整个片段的全局,但是从 addOnSuccessListner() 出来后 Map 将返回 null。
我已经在 onCreateView() 中声明了 Map
static Map<String, Map<String, String>> hospitals ;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
View root = inflater.inflate(R.layout.fragment_home, container, false);
hospitals = new HashMap<>();
.......
.....
return root;
下面是我检索 HospitalData 的代码。
private void readHospitalData()
CollectionReference collectionReference = fStore.collection("hospital Details");
collectionReference.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>()
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots)
for(QueryDocumentSnapshot queryDocumentSnapshot: queryDocumentSnapshots)
Map<String, String> map = new HashMap<>();
map.put("h_name", queryDocumentSnapshot.getString("h_name"));
map.put("h_email", queryDocumentSnapshot.getString("h_email"));
map.put("h_phone", queryDocumentSnapshot.getString("h_phone"));
map.put("h_road", queryDocumentSnapshot.getString("h_road"));
map.put("h_area", queryDocumentSnapshot.getString("h_area"));
map.put("h_city", queryDocumentSnapshot.getString("h_city"));
map.put("h_state", queryDocumentSnapshot.getString("h_state"));
map.put("h_pincode", queryDocumentSnapshot.getString("h_pincode"));
hospitals.put(queryDocumentSnapshot.getId(), map);
Log.d("MAP-->" , hospitals.toString()); // display the Map
);
Log.d("MAP-->" , hospitals.toString()); // but here it will display null
【问题讨论】:
它不应该为空,除非你在onCreateView
之前调用 readHospitalData
。它将为空 collectionReference.get()
是一个异步调用,因此您只需将 Logs 放入 onSuccess
中。
您也可以查看 this。
【参考方案1】:
处理读取和写入数据的 Firebase API 调用是完全异步的。这意味着调用总是立即返回,而不会阻塞代码等待结果。结果会在稍后的某个时间出现,只要他们准备好了。
这就是为什么你在这里得到空值
CollectionReference collectionReference = fStore.collection("hospital Details");
collectionReference.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>()
public void onSuccess(DocumentSnapshot snapshot)
// handle the document snapshot here
);
task.addOnFailureListener(new OnFailureListener()
public void onFailure(Exception e)
// handle any errors here
);
Log.d("MAP-->" , hospitals.toString());
Firebase 消费者 API 出现这种行为的原因: -> 为什么要让 API 的使用者经历使用异步 API 的额外麻烦?我们不能只使用更简单的同步 API 吗?好吧,Firebase 可以为移动应用程序提供同步 API,但是我们会继承两个问题之一,这两个问题都比编写这些额外的代码更糟糕。
1.在应用的主线程上调用同步函数可能会无限期地冻结应用,这是一种糟糕的用户体验。在 android 上,它还可能出现应用程序无响应 (ANR) 对话框软崩溃。
-
为避免使用异步方法阻塞主线程,我们必须管理自己的线程才能正确调用这些 API。这甚至是更多的代码,而且很难正确处理。即使是专业工程师也面临着正确线程行为的挑战。
考虑异步!
Firebase API 对应用主线程的性能很敏感。这意味着任何需要处理磁盘或网络上的数据的 Firebase API 都是以异步方式实现的。这些函数将立即返回,因此您可以在主线程上调用它们而不必担心性能。您所要做的就是使用文档和示例中建立的模式实现回调。
这个问题有一个解决方案,你必须使用 Kotlin-Flow 进行同步调用,通过这个链接:https://developer.android.com/kotlin/flow#callback
【讨论】:
【参考方案2】:我通过使用 Callback
解决了这个问题我创建了 HospitalData.class 并从那里的 firebase 检索数据。通过使用 Callback 接口,我读取了 Fragment
中的数据HospitalData.class
public class HospitalData
FirebaseFirestore fStore = FirebaseFirestore.getInstance();
Map<String, Map<String, String>> hospitals = new HashMap<>();
HospitalCallback hospitalCallback;
HospitalData()
// empty constructor
public void setHospitalCallback(HospitalCallback hospitalCallback)
this.hospitalCallback = hospitalCallback;
void getHospitalData()
CollectionReference collectionReference = fStore.collection("hospital Details");
collectionReference.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>()
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots)
for(QueryDocumentSnapshot queryDocumentSnapshot: queryDocumentSnapshots)
Map<String, String> map = new HashMap<>();
map.put("h_name", queryDocumentSnapshot.getString("h_name"));
map.put("h_email", queryDocumentSnapshot.getString("h_email"));
map.put("h_phone", queryDocumentSnapshot.getString("h_phone"));
map.put("h_road", queryDocumentSnapshot.getString("h_road"));
map.put("h_area", queryDocumentSnapshot.getString("h_area"));
map.put("h_city", queryDocumentSnapshot.getString("h_city"));
map.put("h_state", queryDocumentSnapshot.getString("h_state"));
map.put("h_pincode", queryDocumentSnapshot.getString("h_pincode"));
hospitals.put(queryDocumentSnapshot.getId(), map);
hospitalCallback.DisplayHospitalData(hospitals);
);
interface HospitalCallback
public void DisplayHospitalData(Map<String, Map<String, String>> map);
在我的 HomeFragment.class 中
public class HomeFragment extends Fragment implements HospitalCallback
static Map<String, Map<String, String>> hospitals ;
HospitalData hospitalData;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
View root = inflater.inflate(R.layout.fragment_home, container, false);
hospitals = new HashMap<>();
hospitalData = new HospitalData();
hospitalData.getHospitalData();
hospitalData.setHospitalCallback(this);
return root;
@Override
public void DisplayHospitalData(Map<String, Map<String, String>> map)
Log.d("HOSPITAL DATA-->", map.toString());
【讨论】:
以上是关于全局变量在android studio中返回null [重复]的主要内容,如果未能解决你的问题,请参考以下文章