简体   繁体   中英

Handling RunTimeExceptions of a class

I have a class that extends Application which has a lot of methods like:

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

which wraps a service class.

The catch here is that no method will work if I have no internet on the device. So for instance I am doing:

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

    return ret;
}

Is there a way to wrap every call so I don't have to add the try catch on every method of my Application ?

Without using any third party libraries that might be available on Android, there is no simple way to wrap methods of a class. If you can extract your application functionality into an interface, you can use java.lang.reflect.Proxy to implement your interface - the proxy implementation is a single method that calls your real implementation method, and caches and handles the exception.

I can provide more details if factoring out the code into a separate class and interface is a workable approach for you.

EDIT: Here's the details:

You currently are using myService , which implements the methods. If you don't have one already, create an interface UserService that declares the service methods:

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

And declare this interface on your existing MyService class,

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

To then avoid repetition, the exception handling is implemented as an 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);
           }
       }
   }
}

This is then used as a proxy, in your Application class:

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

You then use the appUserService without needing to worry about catching the NoInternetException.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM