Android общий шаблон для перехвата ошибки сеанса, обработки ошибки с экраном, продолжайте в той же точке до появления ошибки - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть продуктивное Android приложение, использующее действия, фрагменты и IntentServices. Новые требования вынуждают меня интегрировать бэкенд мониторинга / отслеживания, чтобы отслеживать действия, которые пользователь выполняет в приложении. Чтобы упростить проблемный образ, каждая кнопка .setOnClickListener () должна сначала выполнить внутренний бэкэнд-вызов HTTP, а затем продолжить с бизнес-логи c. Я интегрировал бэкэнд мониторинга REST, используя swagger в сочетании с okhttp v.2.7, который я вызываю из задачи asyn c. Первым шагом в приложении теперь является экран входа в систему, который вызывает метод login () на бэкэнде, т. Е. Создает сеанс HTTP и сохраняет маркер безопасного сеанса, возвращаемый бэкэндом. При каждом обращении к бэкэнду автоматически добавляется заголовок HTTP с маркером защищенного сеанса. Я также использую прослушиватели перехвата OkHTTP для регистрации запросов к Android logcat. Кажется, что этот подход работает нормально, но у меня есть проблема с истечением срока действия безопасного токена. Примерно через неделю истекает сеанс с бэкэндом, и приложение Android должно будет инициировать HTTP login () и сохранить новый безопасный токен сеанса. Обратите внимание, что бэкэнд не находится под моим контролем (обновление токенов в бэкенде не работает). До сих пор я мог обрабатывать внезапные ошибки сеанса (HTTP-код 403 возвращается бэкэндом), исследуя ApiException OkHTTP, заканчивая действие указанным кодом результата c, обрабатывая код результата в основном действии путем перехода к действию входа в систему. (конечно, сам пользователь должен вернуться к экрану, который он использовал до того, как произошла ошибка).

Но этот подход требует много кода для каждого возможного случая в зависимости от вызывающего объекта. Как я уже говорил в начале, я использую действия, фрагменты и сервисы намерений, и каждый объект должен вызывать бэкэнд для мониторинга / отслеживания. Таким образом, обработка ошибок должна быть специально адаптирована для каждой сущности, например, фрагменты должны сообщать родительской активности о возникновении и ошибке. Наличие ошибки в службе намерений, конечно, сложнее. (Android Условная навигация JetPack для меня выглядит излишней.)

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

1 Ответ

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

Вот первая попытка, для каждого фрагмента / действия должна быть реализована методика onPostExecute () для обработки указанного c случая ошибки. В решении отсутствует механизм продолжения выполнения ровно через одну строку после navigateToLoginScreenToRenewSession () после возобновления сеанса, это сложная часть. Мне интересно, есть ли у кого-нибудь хорошее решение для этого.

public abstract class AbstractAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {

    public boolean isSessionError() {
    // instanceOf for HTTP exception and check for contained HTTP error code
    }

    protected void storeException(Exception e){
    }
}

public class ActuallyDoSomethingTask extends AbstractAsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... voids) {
     try{
         // do something
     } catch(Exception e){
         storeException(e);
     }
}

public class SomeActivityUsingHttpSession extends Activity {

    private void onClickListener(){
       new ActuallyDoSomethingTask(){
           // specific implementation for activity / fragment case

           protected void onPostExecute(Void voids){
               if(isSessionError){
                   displayToastWithSessionErrorDescription();
                   navigateToLoginScreenToRenewSession();
                   // TODO continue execution after login screen successfully completed, how can we do that easily without huge boiler plate?
               }
           }
       }.execute()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...