在应用程序完成获取并将获取的数据传递给它之后,我应该如何启动一个新的 Activity?
Posted
技术标签:
【中文标题】在应用程序完成获取并将获取的数据传递给它之后,我应该如何启动一个新的 Activity?【英文标题】:How should I start a new Activity, after the application is done fetching and passing the fetched data to it? 【发布时间】:2020-08-04 02:02:38 【问题描述】:在我的应用程序中,我使用联系人数据库并使用 RecyclerView
显示这些联系人。当我点击一个联系人时,我想从数据库中的表中获取它的数据,并将它们加载到一个新的活动中,ContactCard
。我有一个 AsyncTask(),它获取与所选 contactId
匹配的 PhoneNumber
对象,但我还需要从其他表中检索 Address
和 Email
对象。
我希望能够在获取所有相关数据后启动活动,我尝试在联系人RecyclerView
的活动中执行此操作,但由于尚未获取数据,应用程序崩溃了。
我可以使用 Intent 调用新 Activity,但如何确保在启动新 Activity(有效显示此数据)之前先获取来自不同表的数据?
我的一些代码:
public class PhoneNumberRepository
private WorksideDatabase worksideDatabase;
private List<PhoneNumber> returnedNumbers;
private Context mContext;
public PhoneNumberRepository(Context context)
String DB_NAME = "workside_database";
worksideDatabase = Room.databaseBuilder(context, WorksideDatabase.class, DB_NAME).build();
mContext = context;
public List<PhoneNumber> fetchPhoneNumbers(final int id)
new AsyncTask<Integer, Void, List<PhoneNumber>>()
@Override
protected List<PhoneNumber> doInBackground(Integer... ids)
returnedNumbers = worksideDatabase.phoneNumberDao().getPhoneNumbersById(id);
System.out.println(returnedNumbers);
for (PhoneNumber pn : returnedNumbers)
System.out.println("Number: " + pn.getPhoneNumber());
return returnedNumbers;
// This runs in UI when background thread finishes
@Override
protected void onPostExecute(List<PhoneNumber> result)
super.onPostExecute(result);
System.out.println("Entered onPostExecute of fetchPhoneNumbers");
// for (PhoneNumber pn : result)
// Toast.makeText(mContext, pn + "", Toast.LENGTH_SHORT).show();
//
.execute();
return returnedNumbers;
public List<PhoneNumber> getPhoneNumbers(int id)
return fetchPhoneNumbers(id);
联系人片段:
adapter.setOnItemClickListener(
contact ->
Intent viewContact = new Intent(getActivity(), WorksideContactCard.class);
viewContact.putExtra(WORKSIDE_CONTACT, contact);
PhoneNumberRepository phoneNumberRepository =
new PhoneNumberRepository(getActivity().getApplicationContext());
List<PhoneNumber> phoneNumberList;
phoneNumberList = phoneNumberRepository.getPhoneNumbers(contact.getId());
ArrayList<PhoneNumber> arrlistPhoneNumbers =
new ArrayList<>(phoneNumberList);
viewContact.putParcelableArrayListExtra(
WORKSIDE_CONTACT_PHONE_NO, arrlistPhoneNumbers);
startActivity(viewContact);
【问题讨论】:
从 logcat 发布崩溃日志 @karan 好吧,我已经解决了这个问题。本质上,我在 AsyncTask() 完成获取数据之前尝试使用 List您可以在单击一个项目时执行此操作,像这样启动异步任务
adapter.setOnItemClickListener(
contact ->
PhoneNumberRepository phoneNumberRepository =
new PhoneNumberRepository(getActivity().getApplicationContext());
List<PhoneNumber> phoneNumberList;
phoneNumberRepository.getPhoneNumbers(contact.getId());
并将您的 PhoneNumberRepository 更改为此类
public class PhoneNumberRepository
private WorksideDatabase worksideDatabase;
private List<PhoneNumber> returnedNumbers;
private Context mContext;
public PhoneNumberRepository(Context context)
String DB_NAME = "workside_database";
worksideDatabase = Room.databaseBuilder(context, WorksideDatabase.class, DB_NAME).build();
mContext = context;
public void fetchPhoneNumbers(final int id)
new AsyncTask<Integer, Void, List<PhoneNumber>>()
@Override
protected List<PhoneNumber> doInBackground(Integer... ids)
returnedNumbers = worksideDatabase.phoneNumberDao().getPhoneNumbersById(id);
System.out.println(returnedNumbers);
for (PhoneNumber pn : returnedNumbers)
System.out.println("Number: " + pn.getPhoneNumber());
return returnedNumbers;
// This runs in UI when background thread finishes
@Override
protected void onPostExecute(List<PhoneNumber> result)
super.onPostExecute(result);
Intent viewContact = new Intent(context, WorksideContactCard.class);
ArrayList<PhoneNumber> arrlistPhoneNumbers =
new ArrayList<>(result);
viewContact.putParcelableArrayListExtra(
WORKSIDE_CONTACT_PHONE_NO, arrlistPhoneNumbers);
context.startActivity(viewContact);
System.out.println("Entered onPostExecute of fetchPhoneNumbers");
.execute();
public void getPhoneNumbers(int id)
return fetchPhoneNumbers(id);
【讨论】:
是的,这可能就是我需要做的。在onPostExecute
中创建意图,并在其中获取联系人、电话号码、电子邮件和地址对象的数据,然后再显示联系人的数据。【参考方案2】:
将联系人存储在 doInBackground() 方法中的列表中,并在 onPostExecute() 中启动新活动的意图 em> 方法,并使用此意图将联系人列表作为 intent.extra() 变量传递,检索并在调用的活动中使用它们。
【讨论】:
【参考方案3】:将您的存储库类更改为类似的内容
public class PhoneNumberRepository
private WorksideDatabase worksideDatabase;
private List<PhoneNumber> returnedNumbers;
private Context mContext;
private boolean dataDownloaded;
public PhoneNumberRepository(Context context)
String DB_NAME = "workside_database";
worksideDatabase = Room.databaseBuilder(context, WorksideDatabase.class, DB_NAME).build();
mContext = context;
public List<PhoneNumber> fetchPhoneNumbers(final int id)
new AsyncTask<Integer, Void, List<PhoneNumber>>()
@Override
protected List<PhoneNumber> doInBackground(Integer... ids)
returnedNumbers = worksideDatabase.phoneNumberDao().getPhoneNumbersById(id);
System.out.println(returnedNumbers);
for (PhoneNumber pn : returnedNumbers)
System.out.println("Number: " + pn.getPhoneNumber());
return returnedNumbers;
// This runs in UI when background thread finishes
@Override
protected void onPreExecute(List<PhoneNumber> result)
//set flag to false when download starts
dataDownloaded = false;
// This runs in UI when background thread finishes
@Override
protected void onPostExecute(Object obj)
super.onPostExecute(result);
//set flag to true once download completes, you can also check if response is null and update it accordingly
dataDownloaded = true;
System.out.println("Entered onPostExecute of fetchPhoneNumbers");
// for (PhoneNumber pn : result)
// Toast.makeText(mContext, pn + "", Toast.LENGTH_SHORT).show();
//
.execute();
return returnedNumbers;
public List<PhoneNumber> getPhoneNumbers(int id)
return fetchPhoneNumbers(id);
public boolean isDataDownloaded(int id)
return dataDownloaded;
在onItemClick()
中使用此功能,无论您的数据是否下载
if(phoneNumberRepository.isDataDownloaded())
//code to fetch data from phonenumberrepo and start activity
【讨论】:
目前我对获取空联系人没有任何问题。出现问题是因为我有单独的联系人表格,以及存储在单独表格中的“电话号码”、“电子邮件”和“地址”等信息。检索联系人本身是可以的,但我还需要检索相关的电话号码、电子邮件和地址。 @George 是来自本地数据库的数据吗? 是的,并且存储库类正确地获取数据。 嗯好吧,但是如果我在onItemClick()
中调用if(phoneNumberRepository.isDataDownloaded())
,它肯定会在获取数据之前执行,因此dataDownloaded 将始终为false?如果您不相信,我可以试一试。
您可以显示正在下载数据的相应消息,当下载完成并且用户点击项目时,它将带他进入下一个带有数据的活动。以上是关于在应用程序完成获取并将获取的数据传递给它之后,我应该如何启动一个新的 Activity?的主要内容,如果未能解决你的问题,请参考以下文章
将数据传递给 Web 服务获取 - 500(内部服务器错误)