Я новичок в 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 уже выполняет фоновую работу за вас.
Чтобы полностью понять причину проблемы, вам необходимо понимать жизненный цикл своей активности и добавлять журналы для отметки критических событий, которые помогут вам узнать, какой блок кода вызывается в любой момент времени. Поэтому я рекомендую вам добавлять журналы, когда загрузка данных начинается, заканчивается и когда вы скрываете представление или показываете представление, чтобы быть уверенным, что все методы вызываются, а также добавлять журналы в жизненные циклы вашей активности.
Вам действительно не нужно использовать AsyncTaskLoader с Firestore. API-интерфейсы Firestore уже являются асинхронными, и повторить выборку не проблема, потому что сначала она будет извлекаться из кеша. Использование загрузчика просто добавляет намного больше кода без уважительной причины.