Android使用依赖注入简单的自定义类 [英] Android use dependency injection for simple custom class

查看:94
本文介绍了Android使用依赖注入简单的自定义类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在网上搜索了解此功能后,大多数主题或帖子都使用依赖注入 Retrofit 或其他Android有用的库,但我有一些我想要的自定义类使用它与DI,我不能这样做,例如我有简单的自定义类使用 SharePreference ,我正在使用它作为一个单例类

after search on web for learning about this feature most topics or post was using dependency injection for Retrofit or other android useful libraries, but i have some custom class which i want to use that with DI and i can't done it, for example i have simple custom class for using SharePreference and i'm using with that as an Singleton class

在我的代码中我无法将正确的Dagger分配给 SpApplication 类上的组件,以便在活动或片段上使用它

in my code i can't assign correct Dagger to component on SpApplication class to use that on activities or fragments

public class SP {

    private SharedPreferences preferences;
    private Context context;

    public SP(Context context) {
        this.context = context;
    }

    private SharedPreferences getPrefs() {
        return preferences = PreferenceManager.getDefaultSharedPreferences(context);
    }

    public String getString(SharedPrefsTypes propertyName) {
        return getPrefs().getString(propertyName.toString(), "");
    }


    public int getInt(SharedPrefsTypes propertyName) {
        return getPrefs().getInt(propertyName.toString(), 0);
    }
    ...
    public enum SharedPrefsTypes {
        Login
    }
}

现在我正在尝试使用DI:

now i'm trying to use DI for that:

AppModules类:

AppModules class:

@Module
public class AppModules {
    private Context context;

    public AppModules(Context context) {
        this.context = context;
    }

    @Provides
    @Singleton
    SP provideSharePreferences() {
        SP sharePreference = new SP(context);
        return sharePreference;
    }
}

ApplicationComponent class:

@Component(modules = AppModules.class)
public interface ApplicationComponent {
    void inject(ActivityMain activity);
}

SpApplication class:

public class SpApplication extends Application {
    private static SpApplication self;
    private ApplicationComponent component;

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

        self = this;
        component = DaggerApplicationComponent.builder().build();
    }


    public static SpApplication get(Context context) {
        return (SpApplication) context.getApplicationContext();
    }

    public static SpApplication getInstance() {
        return self;
    }

    public ApplicationComponent getComponent() {
        return component;
    }
}

和我的 ActivityMain class:

public class ActivityMain extends AppCompatActivity {
    @Inject
    SP sharePreference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((SpApplication) getApplication()).getComponent().inject(this);
        sharePreference.setInt(SP.SharedPrefsTypes.Login, 0);
    }
}

我收到此错误:

android.app.Application cannot be cast to com.pishguy.yendir.SpApplication

提前致谢

推荐答案

我猜你试图注入 ActivityMain ,但由于你没有提供它的来源,让我告诉你如何注入 SpApplication 。然后只需将相关部分复制到活动

I guess you are trying to inject into ActivityMain, but since you did not provide its source, let me show you how you could inject into SpApplication. Then just copy the relevant parts into your Activity.

我认为您需要更改的内容很少。

Few things I think you need to change.

模块:

您的 AppModules class通常没问题,但我建议你改变你使用 Context 的方式 - 不要将它用作字段,而是将其作为任何其他服务注入。它看起来像这样:

Your AppModules class is generally OK, but I just suggest you to change the way you make use of Context - don't use it as a field, but inject it as any other service. It looks like this:

@Module
public class AppModules {
    private Context context;

    public AppModules(Context context) {
        this.context = context;
    }

    @Provides // this can be non-scoped because anyway the same instance is always returned
    Context provideContext() {
        return this.context;
    }

    @Provides
    @Singleton
    SP provideSharePreferences(Context context) {
        return new SP(context); // use method-local Context
    }
}

组件:


  1. 如果组件注入作用域服务(@Singleton是作用域),则组件本身必须是作用域的

  2. 如果要注入SpApplication类,则将其声明为组件中的注入客户端

考虑到这两点, ApplicationComponent 应如下所示:

Taking into account these two points, ApplicationComponent should look like this:

@Singleton // injects @Singleton scoped services
@Component(modules = AppModules.class)
public interface ApplicationComponent {
    void inject(SpApplication application); // SpApplication is DI client (injection target)
}

客户:

我在 SpApplication 类中更改了一些内容:

I'd change few things in your SpApplication class:


  1. 实例化 ApplicationComponent 的方式不正确

  2. 这不是一个bug ,但你真的不需要 get(上下文) getInstance()方法

  1. The way you instantiate ApplicationComponent is incorrect
  2. This is not a bug, but you don't really need get(Context) and getInstance() methods

此外,由于我将展示如何注入 SpApplication ,我将添加注入逻辑为好(你应该复制给你的实际客户)。

In addition, since I'm showing how you inject into SpApplication, I will add the injection logic as well (which you should copy to your actual clients).

所以, SpApplication (这是DI客户端)应该看起来类似于:

So, SpApplication (which is DI client) should look similar to this:

public class SpApplication extends Application {

    @Inject SP sp; // the dependency that should be injected

    private ApplicationComponent component;

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

        getComponent().inject(this); // this is when the actual injection takes place
    }


    public ApplicationComponent getComponent() {
        if (component == null) {
            // this is the way Dagger components should be instantiated
            component = DaggerApplicationComponent.builder()
                .appModules(new AppModules(this))
                .build();
        }
        return component;
    }
}

如果您执行上述更改,我倾向于相信你会没事的。

If you perform the above changes, I tend to believe that you'll be all right.

BTW,我最近完成了博客文章。如果你要认真对待依赖注入,你可能想检查它。

BTW, I recently completed a blog post about Dagger 2 scopes. You might want to check it if you are going to be serious about dependency injection.

这篇关于Android使用依赖注入简单的自定义类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆