У меня есть класс, который расширяет 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
?
Без использования каких-либо сторонних библиотек, которые могут быть доступны на 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.