[英]Retrieving data from Cloud Firestore with AsynkTaskLoader in Android
我是Android和Firebase的新手,並且遇到了一個我不明白的怪異錯誤。 我有一個RecyclerView,它應該顯示一個字符串列表,該字符串列表的日期后面是一個數字。 現在,我想從Cloud Firestore檢索數據並顯示它。 為此,我使用AsyncTaskLoader,並在loadInBackground()
從Cloud Firestore檢索數據。 現在,當我開始活動時,它會顯示錯誤消息(無論我按了多少次刷新按鈕,它都會一直保持這種行為)。 但是,如果我關閉屏幕然后再打開,它將以我希望的方式顯示數據。 以下是我的代碼
public class MeasureListActivity extends AppCompatActivity implements
MeasuresAdapter.MeasuresAdapterOnClickHandler,
LoaderManager.LoaderCallbacks<String[]> {
private RecyclerView mRecyclerView;
private FirebaseAuth mAuth;
private MeasuresAdapter mMeasuresAdapter;
private TextView mErrorMessageDisplay;
private ProgressBar mLoadingIndicator;
private static final int MEASURES_LOADER_ID = 0;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/* Use AppCompatActivity's method getMenuInflater to get a handle on the menu inflater */
MenuInflater inflater = getMenuInflater();
/* Use the inflater's inflate method to inflate our menu layout to this menu */
inflater.inflate(R.menu.measures_list, menu);
/* Return true so that the menu is displayed in the Toolbar */
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
invalidateData();
getSupportLoaderManager().restartLoader(MEASURES_LOADER_ID, null, this);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_measure_list);
mAuth = FirebaseAuth.getInstance();
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview_measures);
mErrorMessageDisplay = (TextView) findViewById(R.id.tv_error_message_display);
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mMeasuresAdapter = new MeasuresAdapter(this);
mRecyclerView.setAdapter(mMeasuresAdapter);
mLoadingIndicator = (ProgressBar) findViewById(R.id.pb_loading_indicator);
int loaderId = MEASURES_LOADER_ID;
LoaderManager.LoaderCallbacks<String[]> callback = MeasureListActivity.this;
Bundle bundleForLoader = null;
getSupportLoaderManager().initLoader(loaderId, bundleForLoader, callback);
}
@Override
public Loader<String[]> onCreateLoader(int id, final Bundle loaderArgs) {
return new AsyncTaskLoader<String[]>(this) {
String[] mWMeasuresData = null;
@Override
protected void onStartLoading() {
if (mWMeasuresData != null) {
deliverResult(mWMeasuresData);
} else {
mLoadingIndicator.setVisibility(View.VISIBLE);
forceLoad();
}
}
private String[] aux;
@Override
public String[] loadInBackground() {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("medidas").whereEqualTo("id_user", "3Aq3g0czkarT8GIbyESV").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
QuerySnapshot snapshot = task.getResult();
int tam = snapshot.getDocuments().size();
aux = new String[tam];
for (int i = 0; i < tam; i++) {
String temp = "";
DocumentSnapshot doc = snapshot.getDocuments().get(i);
temp += doc.get("fecha") + " ";
temp += doc.get("valor");
aux[i] = temp;
}
}
}
});
return aux;
}
public void deliverResult(String[] data) {
mWMeasuresData = data;
super.deliverResult(data);
}
};
}
@Override
public void onLoadFinished(Loader<String[]> loader, String[] data) {
mLoadingIndicator.setVisibility(View.INVISIBLE);
mMeasuresAdapter.setMeasuresData(data);
if (null == data) {
showErrorMessage();
} else {
showMeasuresDataView();
}
}
@Override
public void onLoaderReset(Loader<String[]> loader) {
}
private void invalidateData() {
mMeasuresAdapter.setMeasuresData(null);
}
private void showMeasuresDataView() {
/* First, make sure the error is invisible */
mErrorMessageDisplay.setVisibility(View.INVISIBLE);
/* Then, make sure the weather data is visible */
mRecyclerView.setVisibility(View.VISIBLE);
}
private void showErrorMessage() {
/* First, hide the currently visible data */
mRecyclerView.setVisibility(View.INVISIBLE);
/* Then, show the error */
mErrorMessageDisplay.setVisibility(View.VISIBLE);
}
@Override
public void onClick(String measure) {
Context context = this;
Class destinationClass = DetailMeasureActivity.class;
Intent intentToStartDetailActivity = new Intent(context, destinationClass);
intentToStartDetailActivity.putExtra(Intent.EXTRA_TEXT, measure);
startActivity(intentToStartDetailActivity);
}
}
您能幫我嗎?...提前感謝
首先,我認為當您調用以下代碼塊時:
mLoadingIndicator.setVisibility(View.VISIBLE);
forceLoad();
您還應該隱藏錯誤消息視圖。
另外,更重要的是,您不需要AsyncTaskLoader即可從firestore中獲取數據,firebase firestore已經為您處理了后台工作。
為了能夠全面了解問題的根源,您需要了解活動的生命周期,並添加日志以標記重要事件,以幫助您隨時了解哪個代碼塊被調用。 因此,我鼓勵您在數據加載開始,完成,隱藏視圖或顯示視圖時添加日志,以確保所有方法都已調用,並且還將日志添加到活動生命周期中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.