Обработка RunTimeException для класса

1

У меня есть класс, который расширяет Application, который имеет много методов, таких как:

public User getUser(String name);
public List<User> getFriends(User user);
public List<Game> getGames(User user);

который обертывает класс службы.

Ловушка здесь заключается в том, что никакой метод не будет работать, если у меня нет интернета на устройстве. Так, например, я делаю:

public User getUser(String name) {
        User ret = null;
        try {
            return myService.getUser(name);
        } catch (NoInternetException e) {
            NoInternetToast.show(this);
        }

    return ret;
}

Есть ли способ обернуть каждый вызов, поэтому мне не нужно добавлять try catch для каждого метода моего Application?

  • 0
    Это не имеет прямого отношения к вашему вопросу, но может иметь смысл использовать ConnectivityManager для обнаружения существования интернет-соединения вместо того, чтобы перехватывать исключение NoInternetException ( developer.android.com/reference/android/net/… )
  • 0
    @ Даниэль Лью: Да, я знаю это, но если я сделаю это, мне нужно изменить каждое представление в моем приложении, чтобы отключить ссылки, если интернет отключен.
Показать ещё 1 комментарий
Теги:
exception-handling

1 ответ

3
Лучший ответ

Без использования каких-либо сторонних библиотек, которые могут быть доступны на Android, нет простого способа обернуть методы класса. Если вы можете извлечь функциональность вашего приложения в интерфейс, вы можете использовать java.lang.reflect.Proxy для реализации вашего интерфейса - реализация прокси-сервера один метод, который вызывает ваш реальный метод реализации, а также кэширует и обрабатывает исключение.

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

EDIT: Здесь подробности:

В настоящее время вы используете myService, который реализует методы. Если у вас его еще нет, создайте интерфейс UserService, который объявит методы службы:

public interface UserService {
  User getUser(String name);
  List<User> getFriends(User user);
  List<Game> getGames(User user);
}

И объявите этот интерфейс в существующем классе myService,

class MyService implements UserService {
     // .. existing methods unchanged 
     // interface implemented since methods were already present
}

Чтобы избежать повторения, обработка исключений реализуется как InvocationHandler

class HandleNoInternet implements InvocationHandler {
   private final Object delegate;   // set fields from constructor args
   private final Application app;

   public HandleNoInternet(Application app, Object delegate) {
      this.app = app; 
      this.delegate = delegate;
   }
   public Object invoke(Object proxy, Method method, Object[] args) {
       try {
           // invoke the method on the delegate and handle the exception
           method.invoke(delegate, args);
       } catch (Exception ex) {
           if ( ex.getCause() instanceof NoInternetException ) {
             NoInternetToast.show(app);
           } else {
             throw new RuntimeException(ex);
           }
       }
   }
}

Затем это используется как прокси-сервер в классе Application:

InvocationHandler handler = new HandleNoInternet(this, myService);
UserService appUserService = (UserService)Proxy.newProxyInstance(
   getClass().getClassLoader(), new Class[] { UserService.class }, handler);

Затем вы используете appUserService, не беспокоясь о том, чтобы поймать NoInternetException.

  • 0
    Имеет ли смысл использовать прокси для достижения СУХОГО?
  • 0
    @ Макарс - Очень даже. В обычной java Proxying является основой многих сред AOP, и аспекты являются одним из способов избежать повторения. В этом случае аспект является последовательной обработкой исключений. С помощью прокси вы определяете желаемое поведение только один раз и применяете его ко всем методам, для которых требуется согласованная обработка исключений. Кроме инструментов генерации кода, я не вижу другой альтернативы.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню