本文介紹了如何在Java for Android中修改新創建的監聽器中的外部布爾值的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我有一個Android片段類,它有一個在單擊按鈕后在外部Firebase數據庫上寫入內容的方法。
public class FR_Fragment extends Fragment implements View.OnClickListener {
public void onClick(View view) {
boolean writingSuccessfull = false;
boolean writingNotSuccessfull = false;
firebase_DB.child(id).setValue(currentOrder).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
writingSuccessfull = true;
writingNotSuccessfull = false;
Log.e("dbTAG", "Data successfully written.");
}
else {
writingSuccessfull = false;
writingNotSuccessfull = true;
Log.e("dbTAG", task.getException().getMessage());
}
}
});
}
}
但是,我不知何故無法訪問我在OnCompleteListener的onClick方法中定義的布爾變量writingSuccessfull
和writingNotSuccessfull
。在顯示的代碼中,我得到了一個錯誤&變量‘WritingSuccessFull’是從內部類內部訪問的,需要是最終的或有效的最終的
當我讓Android Studio解決此問題時,代碼如下所示:
public class FR_Fragment extends Fragment implements View.OnClickListener {
public void onClick(View view) {
final boolean[] writingSuccessfull = { false };
final boolean[] writingNotSuccessfull = { false };
firebase_DB.child(id).setValue(currentOrder).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
writingSuccessfull[0] = true;
writingNotSuccessfull[0] = false
Log.e("dbTAG", "Data successfully written.");
}
else {
writingSuccessfull[0] = false;
writingNotSuccessfull[0] = true
Log.e("dbTAG", task.getException().getMessage());
}
}
});
}
}
現在我可以執行代碼了,但是布爾值不會更改,即使執行了偵聽器中的代碼。我也嘗試了一下,在布爾變量前沒有加上&最終&。但這并沒有改變任何事情。我不能修改此監聽程序中的布爾變量。但這是我需要做的事情,因為我想知道數據是否已成功寫入數據庫。
知道我為什么會遇到這個問題嗎?如何解決它?我將感謝您的每條評論。
更新:以下是更新后的代碼,其中包含Volatile和AericBoolas:
public class FR_Fragment extends Fragment implements View.OnClickListener {
private volatile AtomicBoolean writingOrderToTheDatabaseWasSuccessful;
private volatile AtomicBoolean writingOrderToTheDatabaseWasNotSuccessful;
...
public void onClick(View view) {
int internalCounterAttempsWriteDataInTheFBDatabase =0;
writingOrderToTheDatabaseWasSuccessful = new AtomicBoolean (false);
writingOrderToTheDatabaseWasNotSuccessful = new AtomicBoolean (false);
while(writingOrderToTheDatabaseWasSuccessful.get() == false && writingOrderToTheDatabaseWasNotSuccessful.get()==false) {
internalCounterAttempsWriteDataInTheFBDatabase++;
Log.e("LogTag", "internalCounterAttempsWriteDataInTheFBDatabase: " +internalCounterAttempsWriteDataInTheFBDatabase );
Log.e("LogTag", "writingOrderToTheDatabaseWasSuccessful: " + writingOrderToTheDatabaseWasSuccessful.get());
Log.e("LogTag", "writingOrderToTheDatabaseWasNotSuccessful: " + writingOrderToTheDatabaseWasNotSuccessful.get());
DatabaseReference rootRef = FirebaseDatabase.getInstance("https://drink-server-db-default-rtdb.europe-west1.firebasedatabase.app").getReference();
DatabaseReference ordersRef = rootRef.child("orders");
String id =...;
FirebaseDBItem_Order currentOrder = ...;
ordersRef.child(id).setValue(currentOrder).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
writingOrderToTheDatabaseWasSuccessful.set(true);
writingOrderToTheDatabaseWasNotSuccessful.set(false);
Log.e("dbTAG", "Data successfully written.");
Log.e("LogTag", "Listener: writingOrderToTheDatabaseWasSuccessful: " + writingOrderToTheDatabaseWasSuccessful.get());
Log.e("LogTag", "Listener: writingOrderToTheDatabaseWasNotSuccessful: " + writingOrderToTheDatabaseWasNotSuccessful.get());
} else {
Log.e("dbTAG", task.getException().getMessage());
}
}//end method onComplete
});//end addOnCompleteListener
if (internalCounterAttempsWriteDataInTheFBDatabase >=10) {
writingOrderToTheDatabaseWasNotSuccessful.set(true);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}//end while loop
Log.e("LogTag", "EndWhile: writingOrderToTheDatabaseWasSuccessful: " + writingOrderToTheDatabaseWasSuccessful.get());
Log.e("LogTag", "EndWhile: writingOrderToTheDatabaseWasNotSuccessful: " + writingOrderToTheDatabaseWasNotSuccessful.get());
//Show a toast about the order
if (writingOrderToTheDatabaseWasSuccessful.get() ==true) {
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(getContext(), getString(R.string.message_orderSubmittedSuccessfully), duration);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
if (writingOrderToTheDatabaseWasNotSuccessful.get() ==true) {
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(getContext(), getString(R.string.message_orderSubmittedNotSuccessfully), duration);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
Navigation.findNavController(...);
}//end method onClick
}//end class
問題在于onComplete方法的異步調用。更改布爾值的代碼不會立即調用,因為它是在異步調用的onComplete方法中調用的。這意味著在我的示例中,onComplete方法中的代碼是在10次While循環迭代之后調用的,而不是在循環期間調用的。現在最大的問題是如何在While循環期間調用onComplete方法中的任何代碼。
更新:以下是運行代碼時來自logcat的(相關)輸出:
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 1
writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 2
E/LogTag: writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 3
writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 4
E/LogTag: writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 5
E/LogTag: writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 6
writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 7
E/LogTag: writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 8
writingOrderToTheDatabaseWasSuccessful: false
E/LogTag: writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 9
writingOrderToTheDatabaseWasSuccessful: false
writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: internalCounterAttempsWriteDataInTheFBDatabase: 10
E/LogTag: writingOrderToTheDatabaseWasSuccessful: false
E/LogTag: writingOrderToTheDatabaseWasNotSuccessful: false
E/LogTag: EndWhile: writingOrderToTheDatabaseWasSuccessful: false
EndWhile: writingOrderToTheDatabaseWasNotSuccessful: true
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
E/LogTag: Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
E/LogTag: Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
E/LogTag: Listener: writingOrderToTheDatabaseWasNotSuccessful: false
E/dbTAG: Data successfully written.
E/LogTag: Listener: writingOrderToTheDatabaseWasSuccessful: true
Listener: writingOrderToTheDatabaseWasNotSuccessful: false
結果是該項在FireBase數據庫中保存了10次。我想要的是嘗試在Firebase數據庫中存儲該項目一次。如果這是成功的,循環應該停止,并且應該有一個祝酒詞告訴它是成功的。如果不成功,則循環應嘗試10次(延遲1秒)。如果嘗試10次后仍無法將該項目存儲在FireBase數據庫中,則應停止循環,并且應顯示一條吐司消息,告知無法存儲該項目。
推薦答案
創建擴展Android視圖模型的自定義類
public class MyViewModel extends AndroidViewModel{
private MutableLiveData<Boolean> writingSuccessful=new MutableLiveData<>();
public MyViewModel(@NonNull Application application)
{
// you can do any other stuff here if you want
}
public void setBooleanWritingSuccessful(Boolean b)
{
writingSuccessful.setValue(b);
}
public LiveData<Boolean> getBooleanWritingSuccessful()
{
return writingSuccessful;
}
}
然后在片段中使用此自定義視圖模型類來觀察值的更改
public class FR_Fragment extends Fragment implements View.OnClickListener {
private MyViewModel myViewModel;
private boolean writingSuccessfull= false;
@Override
public void onCreate(Bundle savedInstanceState)
{
// your stuffs
// initialize viewmodel
myViewModel=new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
}
@Override
public void onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// set your viewmodel for observing the changes in boolean values.
myViewModel.getBooleanWritingSuccessful().observe(getViewLifecycleOwner(),new Observer<Boolean>(){
@Override
public void onChanged(Boolean b)
{
// update your writingSuccessful variable here.
writingSuccessfull=b;
}
});
}
// In onClick update your viewmodel's mutablelivedata;
public void onClick(View view) {
...
firebase_DB.child(id).setValue(currentOrder).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
//writingSuccessfull=true;
//writingNotSuccessfull= false;
//update the viewmodel's mutableLiveData
myViewModel.setBooleanWritingSuccessful(true);
Log.e("dbTAG", "Data successfully written.");
} else {
//writingSuccessfull=false;
//writingNotSuccessfull= true;
//update the viewmodel's mutableLiveData
myViewModel.setBooleanWritingSuccessful(false);
Log.e("dbTAG", task.getException().getMessage());
}
}
});
}
}
這是MVVM體系結構的一個簡單片段。希望它現在起作用了。謝謝。
這篇關于如何在Java for Android中修改新創建的監聽器中的外部布爾值的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,