Picasso加载Firestore存储图片仅重启后可见、onActivityResult无回调求助
问题根因
- 跳转逻辑错误:你在
AddJourney中调用startActivityForResult启动HomePage,所以onActivityResult只会回调到AddJourney,不会回到HomePage,完全用反了启动逻辑 - 列表数据仅加载一次:
HomePage的列表数据只在onCreate中执行了一次一次性拉取,从AddJourney返回后没有触发重新拉取,也没有监听Firestore的数据变更,自然拿不到最新上传的图片URL - 异步时序问题:你在添加行程后直接跳转,此时图片上传、URL写入Firestore的异步操作还没执行完,就算立刻拉取也拿不到最新的图片地址
- Picasso未做异常处理:空URL或者地址无效时没有占位兜底,也没有错误提示
修复方案
1. 修正跳转逻辑
修改HomePage.java
修改添加按钮的点击事件,用startActivityForResult启动AddJourney:
case R.id.add_journey: Intent intent_add = new Intent(HomePage.this, AddJourney.class); startActivityForResult(intent_add, 1001); // 自定义请求码 break;
在HomePage中重写onActivityResult,返回时触发列表刷新:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1001 && resultCode == RESULT_OK) { loadDataInListView(); // 返回时刷新列表 } }
修改loadDataInListView方法,支持重复调用刷新
private void loadDataInListView() { db.collection("users").document(userID).collection("journeys").get() .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot queryDocumentSnapshots) { dataArrayList.clear(); // 先清空旧数据 if(!queryDocumentSnapshots.isEmpty()){ List<DocumentSnapshot> list = queryDocumentSnapshots.getDocuments(); for(DocumentSnapshot d : list){ Data data = d.toObject(Data.class); dataArrayList.add(data); } // 不要每次新建Adapter,改为更新数据后通知刷新 if(listView.getAdapter() == null){ Adapter adapter = new Adapter(HomePage.this, dataArrayList); listView.setAdapter(adapter); }else{ ((Adapter)listView.getAdapter()).notifyDataSetChanged(); } } else { Toast.makeText(HomePage.this, "No data found in database", Toast.LENGTH_SHORT).show(); // 空数据也要刷新Adapter if(listView.getAdapter() != null){ ((Adapter)listView.getAdapter()).notifyDataSetChanged(); } } } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(HomePage.this, "Fail to load data..", Toast.LENGTH_SHORT).show(); } }); }
2. 修正AddJourney的返回逻辑
删除原有跳转HomePage的代码,等所有异步操作完成后再返回:
case R.id.add: addJourney(); // 删掉下面这两行错误代码 // Intent intent = new Intent(AddJourney.this, HomePage.class); // intent.setFlags(0); // startActivityForResult(intent, 78); break;
修改addJourney方法,等图片URL写入Firestore成功后再返回:
private void addJourney() { jTitle = title.getText().toString(); jDescription = description.getText().toString(); Map<String, String> data = new HashMap<>(); data.put("title", jTitle); data.put("description", jDescription); data.put("journeyID", null); data.put("imgUrl", null); fStore.collection("users").document(userID).collection("journeys").add(data) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { Toast.makeText(AddJourney.this, "Successfully added journey!", Toast.LENGTH_SHORT).show(); // 先更新journeyID documentReference.update("journeyID", documentReference.getId()) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void unused) { // 上传图片 filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { // 写入图片URL成功后再返回 documentReference.update("imgUrl", uri.toString()) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void unused) { setResult(RESULT_OK); finish(); // 关闭当前页回到HomePage } }); } }); } }); } }); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(AddJourney.this, "Failed to add data", Toast.LENGTH_SHORT).show(); } }); }
3. 优化Picasso加载逻辑
修改Adapter的getView方法,添加占位和错误处理:
if(data.getImgUrl() != null && !data.getImgUrl().isEmpty()){ Picasso.get() .load(data.getImgUrl()) .placeholder(R.drawable.ic_default_image) // 替换为你自己的占位图 .error(R.drawable.ic_error_image) // 替换为你自己的错误图 .into(imageView); }else{ imageView.setImageResource(R.drawable.ic_default_image); }
可选优化:使用Firestore实时监听替代手动刷新
如果不需要手动触发刷新,可以把get()改为addSnapshotListener,Firestore数据变化时自动更新列表,不用每次返回都拉取:
// 在onCreate中调用一次即可 private void listenToJourneyData() { db.collection("users").document(userID).collection("journeys") .addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) { if(error != null){ Toast.makeText(HomePage.this, "数据监听失败", Toast.LENGTH_SHORT).show(); return; } dataArrayList.clear(); for(DocumentSnapshot d : value.getDocuments()){ Data data = d.toObject(Data.class); dataArrayList.add(data); } if(listView.getAdapter() == null){ Adapter adapter = new Adapter(HomePage.this, dataArrayList); listView.setAdapter(adapter); }else{ ((Adapter)listView.getAdapter()).notifyDataSetChanged(); } } }); }
内容的提问来源于stack exchange,提问作者EnCoder2000
相关产品推荐
相关产品推荐

