2010-08-13 4 views
1

j'ai une classe qui étend Application qui a beaucoup de méthodes telles que:manipulation RuntimeExceptions d'une classe

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

qui enveloppe une classe de service.

Le problème ici est qu'aucune méthode ne fonctionnera si je n'ai pas d'Internet sur l'appareil. Donc, par exemple, je fais:

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

    return ret; 
} 

est-il un moyen d'envelopper chaque appel, donc je n'ai pas d'ajouter la prise d'essai sur toutes les méthodes de mon Application?

+0

Ceci n'est pas directement lié à votre question, mais il peut être judicieux d'utiliser ConnectivityManager pour détecter l'existence d'une connexion Internet au lieu d'intercepter l'exception NoInternet (http://developer.android.com/reference/android/net/ ConnectivityManager.html) –

+0

@Daniel Lew: Oui, je le sais, mais si je le fais, j'ai besoin de modifier chaque vue de mon application pour désactiver les liens si Internet est désactivé. – Macarse

+0

Désactiver les liens peut-être mieux pour votre application à long terme de toute façon, UI-sage. Juste une pensée. :) –

Répondre

3

Sans utiliser de bibliothèques tierces pouvant être disponibles sur Android, il n'existe pas de moyen simple d'encapsuler les méthodes d'une classe. Si vous pouvez extraire la fonctionnalité de votre application dans une interface, vous pouvez utiliser java.lang.reflect.Proxy pour implémenter votre interface - l'implémentation du proxy est une méthode unique qui appelle votre méthode d'implémentation réelle, et met en cache et gère l'exception.

Je peux fournir plus de détails si l'affacturage du code dans une classe distincte et une interface est une approche réalisable pour vous.

EDIT: Voici les détails:

Vous êtes myService, qui met en œuvre les méthodes. Si vous ne possédez pas déjà, créer un UserService d'interface qui déclare les méthodes de service:

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

Et déclarer cette interface sur votre classe MyService existante,

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

Pour ensuite éviter les répétitions, l'exception la manipulation est mise en œuvre en tant 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); 
      } 
     } 
    } 
} 

Il est ensuite utilisé comme proxy, dans votre classe d'application:

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

Vous utilisez ensuite appUserService sans avoir à vous soucier de l'exception NoInternetException.

+0

Est-il logique d'utiliser un proxy pour atteindre DRY? – Macarse

+0

@Macarse - Tout à fait. En java régulier, le proxy est l'épine dorsale de nombreux frameworks AOP, et les aspects sont une façon d'éviter de se répéter. Dans ce cas, l'aspect est la gestion cohérente des exceptions. Avec le proxy, vous définissez le comportement souhaité une seule fois et l'appliquez à toutes les méthodes pour lesquelles vous souhaitez une gestion cohérente des exceptions. À part les outils de génération de code, je ne vois pas d'autre alternative. – mdma

+0

cool. Pouvez-vous me donner un aperçu de la façon de l'appliquer à mon exemple? – Macarse