Я знаю, что на вопрос о том, как общаться между службой и деятельностью, ответили много раз, но я также хочу, чтобы мой собственный способ сделать это, чтобы его пересмотреть, и знать, является ли его приемлемым и правильным способом сделать это и каковы недостатки того, как я справился с этим. Во-первых, я сформулирую выражение о проблеме как можно подробнее.
Мне нужно создать приложение, в котором я использую службу сообщений Firebase для обмена данными между двумя устройствами. Скажем, его похожая на Убер система. Одно приложение предназначено для поставщика услуг (водителя) и для клиента (пассажира). Когда пассажир просит путешествовать с их местоположением, водители в определенном радиусе получат push-уведомление с полезной нагрузкой с использованием Firebase. Служба Firebase работает в фоновом режиме. Когда служба получает push-уведомление, onMessageReceived
метод onMessageReceived
. Генерируется событие. Я не использую Firebase здесь для уведомлений, но на самом деле передач данных между устройствами, когда мне нужно, используя data
поля Firebase нажимного уведомления. Теперь приложение-драйвер получит координаты того, где пользователь хочет, чтобы автомобиль находился в полезной нагрузке Push-уведомления Firebase. Я могу просто начать работу с этими данными в дополнительных функциях и показать драйверу, что запрос получен.
Теперь со стороны клиента после того, как клиент отправляет запрос, они переходят к следующему действию, где им показывают вид экрана загрузки, который говорит им ждать, пока один из драйверов примет их запрос. Когда один из драйверов принимает этот пользовательский запрос, этот пользователь теперь получит уведомление Push-Firebase с информацией о назначенных драйверах в полезной нагрузке push-уведомления. Опять же, целью является не генерировать никаких уведомлений, а передавать данные между устройствами.
Теперь, когда вы понимаете прецедент, я перейду к проблеме.
Проблема возникает, когда пользователь отправляет запрос и переходит к следующему экрану ожидания, на котором показан экран загрузки, который говорит им ждать, пока запрос ожидает, чтобы его принял один из драйверов. Когда водитель принимает запрос, как я сказал, пользователь получит уведомление Push-Firebase с информацией о драйвере в полезной нагрузке push-уведомления. Как мне установить связь между сервисом и активностью, чтобы сообщить активности прекратить показ экрана загрузки и заполнить TextView данными, полученными в полезной нагрузке push-уведомления.
Вот как я справился с этим. Предположим, что у меня есть активность с именем AwaitingDriver
, которое TextView заполняется данными драйвера. Но в настоящее время активность показывает экран загрузки, потому что запрос еще не принят. Теперь пользователь получает push-уведомление с информацией о драйвере в службе, работающей в фоновом режиме, и никак не связан с ней. Вот мой метод onMessageReceived
@Override
public void onMessageReceived(RemoteMessage remoteMessage){
SharedPreferences rideInfoPref = getSharedPreferences(getString(R.string.rideInfoPref), MODE_PRIVATE);
SharedPreferences.Editor rideInfoPrefEditor = rideInfoPref.edit();
String msgType = remoteMessage.getData().get("MessageType");
if (msgType.equals("RequestAccepted")){
rideInfoPrefEditor.putBoolean(getString(R.string.is_request_accepted), true);
rideInfoPrefEditor.putString(getString(R.string.driver_phone), remoteMessage.getData().get("DriverPhone"));
rideInfoPrefEditor.putString(getString(R.string.driver_lat), remoteMessage.getData().get("DriverLatitude"));
rideInfoPrefEditor.putString(getString(R.string.driver_lng), remoteMessage.getData().get("DriverLongitude"));
rideInfoPrefEditor.commit();
AwaitingDriver.requestAccepted(); // A static method in AwaitingDriver Activity
}
}
Здесь AwaitingDriver.requestAccepted()
является статическим методом действия AwaitingDriver
. Внутри самой активности AwaitingDriver
, которая показывает диалог прогресса, чтобы сообщить клиенту ждать, вот что делает метод AwaitingDriver.requestAccepted()
.
public static void requestAccepted(){
try{
awaitingDriverRequesting.dismiss(); //ProgressDialog for telling user to wait
}catch (Exception e){
e.printStackTrace();
}
if (staticActivity != null){
staticActivity.new TaskFindSetValues().execute();
}
}
Здесь staticActivity
является статическим объектом класса активности AwaitingDriver
объявленного внутри этого класса. Я устанавливаю его значение в onResume
и onPause
. Значение, если активность находится впереди, показывая на экране, только тогда значение staticActivity
не будет равно null
. Вот методы onResume
и onPause
.
@Override
public void onResume(){
super.onResume();
staticActivity = this;
Boolean accepted = rideInfoPref.getBoolean(getString(R.string.is_request_accepted), false);
if (accepted){
new TaskFindSetValues().execute();
}
}
@Override
protected void onPause(){
super.onPause();
staticActivity = null;
}
Здесь TaskFindSetValues
- это AsyncTask, определенная внутри класса активности AwaitingDriver
. Вот код для TaskFindSetValues
public class TaskFindSetValues extends AsyncTask<String, Void, String>{
String phone;
String lat;
String lng;
@Override
protected void onPreExecute(){
SharedPreferences pref = getSharedPreferences(getString(R.string.rideInfoPref), MODE_PRIVATE);
phone = pref.getString(getString(R.string.driver_phone), "");
lat = pref.getString(getString(R.string.driver_lat), "");
lng = pref.getString(getString(R.string.driver_lng), "");
}
@Override
protected String doInBackground(String... arg0){
return null;
}
@Override
protected void onPostExecute(String returnValue){
awaitingDriverPhone.setText(phone); //setting values to the TextViews
awaitingDriverLat.setText(lat);
awaitingDriverLng.setText(lng);
}
}
Просмотрите этот код и расскажите мне о недостатках этого, а не о других решениях, и если бы вы также могли объяснить предлагаемый способ в том же примере, я был бы очень благодарен.