如何避免为每个视图添加注入方法?

目前要在活动中获得例如毕加索的实例,我需要向AppComponent添加注入方法。 如何避免添加注入方法,因为我有很多的片段和视图应该注入它:

AppComponent.class:

@ForApplication
@Singleton
@Component(
        modules = {AppModule.class,OkHttpClientModule.class,NetworkApiModule.class,NetworkAuthModule.class})
public interface AppComponent {
    void inject(Fragment1 obj);
    void inject(Fragment2 obj);
    void inject(Fragment3 obj);
    void inject(Fragment4 obj);    
    void inject(Fragment5 obj);    
    void inject(Fragment6 obj);
    ...
    }

Fragment1.class

public class Fragment1 extends Fragment {
    @Inject Picasso mPicasso;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyApplication.getComponent(getContext()).inject(this);
    }
}

我的课程 :

AppModule.class:

@Module
public class AppModule {
    private MyApplication mApplication;

    public AppModule(@NonNull MyApplication mApplication) {
        this.mApplication = mApplication;
    }

    @Provides
    @NonNull
    @Singleton
    public Application provideApplication() {
        return mApplication;
    }


   @Provides
   @ForApplication
    Context provideContext(){
        return mApplication;
    }

    @Provides
    @Singleton
    Picasso providesPicasso(@ForApplication Context context) {
        return new Picasso.Builder(context).build();
    }
}

ForApplication.class:

@Scope
@Retention(RUNTIME)
public @interface ForApplication {
}

MyApplication.class

public class MyApplicationextends Application {
    static Context mContext;
    private AppComponent component;
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;

        setupComponent();
    }

    private void setupComponent() {
        component = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
        component.inject(this);
    }

    public AppComponent getComponent() {
        if (component==null)
            setupComponent();
        return component;
    }



public static AppComponent getComponent(Context context) {
        return ((MyApplication) context.getApplicationContext()).getComponent();
    }

UPDATE

我还想为片段注入适配器,如果我将注入添加到BaseFragment,则BaseFragment将拥有所有子片段的所有适配器


一种解决方案是使用继承进行注入。

只需用@Inject Picasso实例定义一个BaseFragment,在你的DaggerComponent中为这个BaseFragment创建一个注入方法,并在BaseFragment的onCreate方法中调用它。 像Fragment1,2 ...这样的更具体的片段可以从这个BaseFragment继承并使用Picasso实例。


解决方案是你可以做的继承ex:使用扩展活动或片段,并在这些类中的onCreate()注入

下面是我做的例子:

Graph.java

@Singleton
@Component(modules = {
        AppModule.class,
})

public interface Graph {

    void inject(BaseActivity activity);
    void inject(BaseFragment fragment);
}

BaseActivity.java

public class BaseActivity extends AppCompatActivity {
    protected List<Subscription> mSubscriptions;

    @Inject
    protected SharedDB dm;

    @Inject
    protected RestApi restApi;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getGraph().inject(this);
    }

    public Graph getGraph() {
        return MyApplication.graph(this);
    }

    //...
}

BaseFragment.java

public class BaseFragment extends Fragment {

    protected List<Subscription> mSubscriptions;
    protected Unbinder unbinder;

    @Inject
    protected SharedDB dm;

    @Inject
    protected RestApi restApi;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getGraph().inject(this);
    }

    public Graph getGraph() {
        return MyApplication.graph(getActivity());
    }

    //....
}

MyApplication.java

public class MyApplication extends Application {

    private Graph mGraph;

    @Override
    public void onCreate() {
        super.onCreate();

        setGraph(DaggerGraph.builder()
                .appModule(new AppModule(this))
                .build());
    }

    public Graph getGraph() {
        return mGraph;
    }

    public void setGraph(Graph graph) {
        mGraph = graph;
    }

    public static Graph graph(Context context) {
        DominoApp app = (DominoApp) context.getApplicationContext();
        return app.getGraph();
    }

    //....
}

那这个呢?

public final class MySimpleDelegate {

    @Inject
    protected Picasso picasso;

    @Inject
    protected Lazy<AdapterOne> lazyAdapterOne;

    @Inject
    protected Provider<AdapterTwo> providerAdapterTwo;

    public MySimpleDelegate(Context context) {
        MyApplication.getComponent(context).inject(this);
    }

    @NonNull
    public void getPicasso() {
        return picasso;
    }

    @NonNull
    AdapterOne getAdapterOne() {
        // the object is injected when the following method is called
        return lazyAdapterOne.get();
    }

    @NonNull
    AdapterTwo getAdapterTwo() {
        // a new instance is created every time this methos is called
        return providerAdapterTwo.get();
    }
}

public class Fragment1 extends Fragment {

    private MySimpleDelegate delegate;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        delegate = new MySimpleDelegate(getContext());

        Picasso picasso = delegate.getPicasso();
        AdapterOne one = delegate.getAdapterOne();
        AdapterTwo two = delegate.getAdapterTwo();
    }
}

顺便说一句,如果唯一的问题是毕加索,它还提供了一个'setSingletonInstance'方法。 看到这个链接

编辑

我相信你可以使用匕首的提供者或惰性工厂达到你想要的。 看到上面的例子。

链接地址: http://www.djcxy.com/p/36217.html

上一篇: How to avoid adding of inject method for each view?

下一篇: Clang Build Errors