Search code examples
androidreflectioninterfacein-app-billing

Android - reflection interface not called


This is the normal way of creating a ServiceConnection interface. If I do it this way everything works fine.

  ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

But if I define a ServiceConnection interface using reflection like below then the only method ever called is hashCode().

ServiceConnection mServiceConnection = (ServiceConnection) java.lang.reflect.Proxy.newProxyInstance(
    ServiceConnection.class.getClassLoader(),
    new java.lang.Class[] { ServiceConnection.class },
    new java.lang.reflect.InvocationHandler() {

        @Override
        public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws java.lang.Throwable {
            log("methodName", method.getName());
            return null;
        }
});

The usage is this:

applicationContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

What am I doing wrong here?

UPDATE

Ok this is very weird...I used debugger and on the line bindService() the debugger showed that mServiceConnection is null while in the previous line i wrote log(Boolean.toString(mServiceConnection == null)) and it printed false (!!??!!). Then I changed the return value of invoke method to return 1;

@Override
public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws java.lang.Throwable {
    log("methodName", method.getName());
    return 1;
}

And now it works... Meanwhile both methods of this interface are void. What is happenning here?


Solution

  • The problem was that the invoke method returned null. Apparently in the system methods at some point the hashCode() method was called and the null value was a problem.

    ServiceConnection mServiceConnection = (ServiceConnection) java.lang.reflect.Proxy.newProxyInstance(
    ServiceConnection.class.getClassLoader(),
    new java.lang.Class[] { ServiceConnection.class },
    new java.lang.reflect.InvocationHandler() {
    
        @Override
        public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws java.lang.Throwable {
            log("methodName", method.getName());
            return 1;
        }
    });
    

    This way it works fine.