質問

I am exploring the world of RoboGuice and have changed an maps activity to now work with it. It is a RoboMapActivity and I have changed my extension of Application to inherit from RoboActivity. I have used @InjectView successfully as below..

public class MyMappingActivity extends RoboMapActivity {

    @InjectView(R.id.mapview)             MapView mMapView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//setContentView injects all of the @values listed above
        setContentView(R.layout.main);
        DgApplication.data.setmPathProfile(this);
        List<Overlay> mapOverlays = mMapView.getOverlays();
        //etc...
    }
    //etc...
}

Now, I have created a ItemizedOverlay and this is where I am stuck. I have added

@Inject MyItemizedOverlay mMyItemizedOverlay;

in MyMappingActivity, and an extract of MyItemizedOverlay is as follows:

class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {

    @Inject
    public MyItemizedOverlay(Drawable marker) {
        super(boundCenterBottom(marker));
    }
}

My problem is I must feed the ItemizedOverlay parent with a default marker, which is in the constructor. I am unable to use @InjectResource to do that as dependency injection does not appear supported in constructors, and I have looked in to the use of bind().to() in a module, but this appears to be for interfaces rather than data types.

I feel like I should be defining the parameter to MyItemizedOverlay in MyMappingActivity where I am performing the @Inject, as I am not able to reference the android resources from inside the constructor without passing them in using a new MyItemizedOverlay().

My questions are twofold:

Firstly, am I heading along the right track? Secondly, how do I resolve the issue with the constructor for MyItemizedOverlay?

役に立ちましたか?

解決

This is what I'd do:

  • Modify your Application class to have somethig like this:

private static Context instance;
@Override
public void onCreate() {
    super.onCreate();
    instance = this;
}
public static Context getContext(){
    return instance;
}

This will allow you to get a context instance wherever you are.

  • Create an AbstractModule like this:

public final class YourGuiceModule extends AbstractModule {
    @Override
    protected void configure() {}

    @Provides public MyItemizedOverlay getMyItemizedOverlay(){
        Resources r = App.getContext().getResources();
        Drawable d = r.getDrawable(R.drawable.something);
        return new MyItemizedOverlay(d);
    }
}

  • Register your module by adding this in your application class:

@Override
protected void addApplicationModules(List<Module> modules) {
    modules.add(new YourGuiceModule());
}

  • Now you can use something like this in your code:

private MyItemizedOverlay mio;
... 

@Inject
public void setMyItemizedOverlay(MyItemizedOverlay blah){
    mio = blah;
}

However, keep in mind that this is too much work compared with just putting this in your class:

MyItemizedOverlay m = new MyItemizedOverlay(getResources().getDrawable(R.drawable.blah));

Dependency injection is nice, but sometimes make things more complex than they should be.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top