Как начать новое действие после того, как приложение завершит выборку и передачу ему полученных данных? - PullRequest
0 голосов
/ 21 апреля 2020

В своем приложении я использую базу данных контактов и отображаю эти контакты, используя RecyclerView. Когда я нажимаю на контакт, я хочу извлечь его данные из таблиц в БД и загрузить их в новую операцию, ContactCard. У меня есть AsyncTask (), который выбирает объекты PhoneNumber, которые соответствуют выбранным contactId, но мне также потребуется извлечь объекты Address и Email из других таблиц.

Я бы хотелось, чтобы можно было начинать задание после получения всех соответствующих данных, и я попытался выполнить это в задании с контактами RecyclerView, но приложение вылетает, поскольку данные еще не получены.

Я могу вызвать новое действие с помощью намерения, но как я могу убедиться, что данные из разных таблиц сначала извлекаются, прежде чем я начну новое действие (которое эффективно отображает эти данные)?

Часть моего кода:

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);
    }
}

ContactsFragment:

     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);
}

Ответы [ 3 ]

0 голосов
/ 21 апреля 2020

Измените свой класс репозитория на что-то вроде этого

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
}
0 голосов
/ 21 апреля 2020

Это можно сделать, когда вы щелкнете по элементу, запустите асинхронную задачу следующим образом

 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);
        }
    }
0 голосов
/ 21 апреля 2020

сохранить контакты в списке в методе doInBackground () и начать намерение нового действия в onPostExecute () , и с этим намерением передайте список контактов в виде переменных intent.extra (), извлеките их и используйте в вызываемой деятельности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...