janishar / android-mvvm-architecture

This repository contains a detailed sample app that implements MVVM architecture using Dagger2, Room, RxJava2, FastAndroidNetworking and PlaceholderView
https://janisharali.com
Apache License 2.0
2.96k stars 934 forks source link

how to use DataManager in non Activity/Fragment class #25

Open Harmeetkaur01 opened 6 years ago

Harmeetkaur01 commented 6 years ago

Hi @amitshekhariitbhu , I'm currently using this architecture only in my project. I'm unable to access datamanager class through @Inject in non activity/fragment class. I have a handler class and want to use datamanager in that class. Can u help me how to do this.

amitshekhariitbhu commented 6 years ago

You can create a method in AppComponent to inject in your class

@Singleton
@Component(modules = {AndroidInjectionModule.class, AppModule.class, ActivityBuilder.class})
public interface AppComponent {

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder application(Application application);

        AppComponent build();

    }

    void inject(MvvmApp app);

    void inject(YourClass yourClass);

}
Harmeetkaur01 commented 6 years ago

@Singleton
@Component(modules = {
        AndroidSupportInjectionModule.class,
        ApplicationModule.class,
        ActivityBuilder.class})
public interface ApplicationComponent extends AndroidInjector<DaggerApplication> {

    void inject(AppController appController);
    void inject(APIHandler apiHandler);

    @Override
    void inject(DaggerApplication daggerApplication);

    @Component.Builder
    interface Builder{
        @BindsInstance
        Builder application(Application application);
        ApplicationComponent build();
    }
}

@amitshekhariitbhu This is my ApplicationComponent class I added a method inject(APIHandler apiHandler) in this and tried getting @Injent DataManager dataManager in ApiHandler class but getting it null, any other thing i need to do in APIHandler class.Let me know if i m missing something

APIHandler class

public class APIHandler {

    /**
     * Activity reference object
     */
    private Activity mActivity;
    /**
     * Debug TAG
     */
    private String TAG = APIHandler.class.getSimpleName();
 @Inject
    DataManager dataManager;

    /**
     * Public Constructor for this class
     *
     * @param mActivity
     * @param webAPIResponseListener
     */
    public APIHandler(Activity mActivity, WebAPIResponseListener webAPIResponseListener) {
        this.mActivity = mActivity;
        this.mResponseListener = webAPIResponseListener;
        postAPICall();
    }
//API call
    public void postAPICall() {
//doing something
if(dataManager != null){
dataManager.setName();
}
}
amitshekhariitbhu commented 6 years ago

You need to get the application component and call inject(this)

Sutirth commented 6 years ago

hey, @amitshekhariitbhu I am also trying to the same unable to do it could you pin down an example over here it would be really of great help. I tried the following

@Singleton
@Component(modules = {AndroidInjectionModule.class, RestModule.class, ActivityBuilder.class, ServiceModule.class})
public interface AppComponent {

    void inject(Customer app);
    void inject(ImageFetcher imageFetcher);
    @Component.Builder
    interface Builder{

        @BindsInstance
        Builder application(Application application);
        AppComponent build();
    }

public class ImageFetcher implements DataFetcher<InputStream> {

    public ImageFetcher(ImageModel imageModel, Context context) {
        this.imageModel = imageModel;
        this.context = context;

    }

    @Override
    public InputStream loadData(Priority priority) throws Exception {

        AppComponent.inject(this);
}

I get an error stating non-static method cannot be reference from static context

amitshekhariitbhu commented 6 years ago

From where you get the AppComponent? It should be from the application class.

Sutirth commented 6 years ago

Hi @amitshekhariitbhu then I am afraid I am doing something wrong my current application class looks like this

public class Customer extends Application implements HasActivityInjector {

    @Inject
    DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;

    @Override
    public DispatchingAndroidInjector<Activity> activityInjector() {
        return activityDispatchingAndroidInjector;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        AndroidThreeTen.init(this);
        JodaTimeAndroid.init(this);

        mInstance = this;

        AppLogger.init();

        DaggerAppComponent.builder()
                .application(this)
                .build()
                .inject(this);
    }

Could you let me know how should I do it?

amitshekhariitbhu commented 6 years ago

Create a variable in application class as AppComponent appComponent. And do like below:

appComponent = DaggerAppComponent.builder()
                .application(this)
                .build();

appComponent.inject(this);

Then get the appComponent through getter from the application class and then inject in the required class.

Sutirth commented 6 years ago

Hi @amitshekhariitbhu , I did as per your suggestion. It worked like a charm. I am able to parse the api. Thanks a bunch for your help