views:

286

answers:

1

I'm doing this in the context of Android, but my problem is understanding Java. I'm somewhat new to both, so hopefully I'm using the correct terminology here.

I've got a number of sub-classes inheriting/extending from my super class (an Android Activity extension) called SuperActivity. I've also defined another class type called Network (which is an Android Service). In my superclass I'm defining an anonymous inner class that implements an (Android) interface called ServiceConnection. That interface specifies (and therefore I'm defining) methods that will be called by the Android system. I have to pass an instance of that anonymous, ServiceConnection-implementing inner class of mine to a method called bindService(), so that the methods inside that anonymous, inner class can be called later.

As I mentioned, I'm subclassing that super-class that defines the anonymous inner class. The methods in that anonymous inner class have to set an instance variable in the subclass instance; that instance variable I need to set is here called mNetwork.

In the superclass:

public class SuperActivity extends Activity {
    protected Network mNetwork;

    protected ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mNetwork = ((Network.NetworkBinder)service).getService();
        }
    }

    void bindNetwork() {
        bindService( new Intent(this, Network.class), mConnection, Context.BIND_AUTO_CREATE);
    }
}

So I create my subclass and call its bindNetwork() method. and apparently the anonymous inner class assigned to mConnection is not an instance member of my subclass, since after the OnServiceConnected() method defined in the anonymous inner class is called, the subclass's instance member called mNetwork is null.

Further, if I take that mConnection variable holding the anonymous inner class and call getClass().getName() on it or toString() on it, it shows itself to be an inner class of my superclass, and not of the subclass.

Obviously I'm not understanding something about java inheritance. I want to have a number of subclasses, each with its own mNetwork variable set by the method inside the anonymous inner class. I don't want to cut and past the definition of the anonymous inner class into each subclass. There's got to be a way. What am I doing wrong?

A: 

There's a way:

  1. Implement an Interface to access a Network field (like NetworkProvider)
  2. extract the anonymous class to a real class
  3. pass a NetworkProvider to the ServiceConnection implementation

Here's a basic snippet to illustrate the approach:

public interface NetworkProvider {
  public void setNetwork(Network network);
  public Network getNetwork();
}

public class SuperActivity extends Activity implements NetworkProvider {
  private Network mNetwork;
  @Override public  void setNetwork(Network network){this.mNetwork = network;}
  @Override Network void getNetwork(){return mNetwork;}

  protected ServiceConnection mConnection = new MyServiceConnection(this);

  // more methods
}

public class MyServiceConnection implements ServiceConnection {  // or 'extends' if it's a class
  private NetworkProvider networkProvider;
  public MyService(NetworkProvider networkProvider) {this.networkProvider = networkProvider;}

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
      networkProvider.setNetwork(((Network.NetworkBinder)service).getService());
  }
}
Andreas_D
Thanks for the reply. Tried it. Got the same result. Near as I can tell (and my certainly level is about 50%) "binding" to a Service in Android is done on a per-application basis, and not on a per-Activity basis. When my second subclassed Activity instance tried to bind to the Service, the Service saw it already bound and didn't call the method indicating the new connection.Android has a class called Appliction. I put the Service-binding code in an instance of that class, and then let my Activities find the Service by asking the Application for the reference. Seems to be working so far.
Adam Mackler