[英]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.