如何在没有上下文的情况下在演示层中使用匕首 2 实现 sharedPreferences?
How to implement sharedPreferences with dagger 2 in presenter layer without context?
如何用 dagger 和 MVP 实现 sharedpreferences,大多数教程都是在 Activity 中编写 sharedpreferences 或向演示者提供上下文。
我需要的是看例子:
- 我应该在
presenter
中写入什么以获得 sharedPreference
不使用 Context
.
module
会是什么样子。
- 我是否需要从
Application
或每次调用 Component
activity 提供上下文。
===更新===
正如 PPartisan 在他的回答中提到的,我不应该在 Presenter
中包含 sharedPreference
.
那么我如何抽象SharedPreferences
后面的API
===更新2===
感谢您的回答PPartisan它真的很好用,请您检查我的代码是否写得完美,或者需要任何调整。
主要Activity
@Inject
MainPresenter presenter;
AppComponent component;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
component = DaggerAppComponent
.builder()
.contextModule(new ContextModule(this))
.build();
component.inject(this);
}
AppModule
@Module
public abstract class AppModule {
@Binds
abstract Repository bindRepository(SharedPrefsRepository prefs);
@Binds
abstract MainPresenterListener listener(MainPresenterListener mListener);
@Provides
static SharedPreferences prefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
}
上下文模块
@Module
public class ContextModule {
private Context context;
public ContextModule(Context context) {
this.context = context;
}
@Provides
Context getContext() {
return context;
}
}
AppComponent
@Component (modules = {AppModule.class, ContextModule.class})
public interface AppComponent {
void inject(MainActivity activity);
}
以最简单的形式(并假设 Context
已经是您的依赖关系图的一部分),然后在您的模块中:
@Provides static SharedPreferences prefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
在您的 Presenter 中:
class Presenter {
private final SharedPreferences prefs;
@Inject
Presenter(SharedPreferences prefs) {
this.prefs = prefs;
}
}
不过,您还可以用它做更多的事情。例如,您可以将 Presenter
的范围限定为 View
的生命周期(即 Activity
或 Fragment
)。此外,最纯粹形式的 "Presenter" 应该对 Android 组件一无所知,因此您可能想要抽象出您自己的 API 背后的 SharedPreferences
。
编辑: 下面是一个示例,说明如何抽象化数据持久性,以便 Presenter 可以保持对 Android 组件的感知:
创建一个合适的接口(这只是持久化和 returns 字符串,因此相应地修改它):
interface Repository {
String read();
void write(String value);
}
创建此 interface
的实例,委托给 SharedPreferences
:
class SharedPrefsRespository implements Repository {
private static final String KEY = "a_key";
private final SharedPreferences prefs;
@Inject
SharedPrefsRepository(SharedPreferences prefs) {
this.prefs = prefs;
}
@Override
String read() {
return prefs.getString(KEY, "");
}
@Override
void write(String value) {
prefs.edit()
.putString(KEY, value == null ? "" : value)
.apply();
}
}
通过将以下内容添加到您的模块(确保您的模块是 abstract
)来告诉 Dagger Repository
的这个实现是您想要使用的那个:
@Binds abstract Repository repository(SharedPrefsRepository prefs);
在你的 Presenter
中,注入 Repository
而不是 SharedPreferences
:
class Presenter {
private final Repository repo;
private View view;
@Inject
Presenter(Repository repo) {
this.repo = repo;
}
void attach(View view) {
this.view = view;
showUserName();
}
//Example of how you might use this repo on something you want to persist
//Imagine a user has entered their username and clicked save...
void onSaveUserName(String username) {
repo.write(username);
}
private void showUserName() {
view.showUsername(repo.read());
}
}
如何用 dagger 和 MVP 实现 sharedpreferences,大多数教程都是在 Activity 中编写 sharedpreferences 或向演示者提供上下文。
我需要的是看例子:
- 我应该在
presenter
中写入什么以获得 sharedPreference 不使用Context
. module
会是什么样子。- 我是否需要从
Application
或每次调用Component
activity 提供上下文。
===更新===
正如 PPartisan 在他的回答中提到的,我不应该在 Presenter
中包含 sharedPreference
.
那么我如何抽象SharedPreferences
后面的API
===更新2===
感谢您的回答PPartisan它真的很好用,请您检查我的代码是否写得完美,或者需要任何调整。
主要Activity
@Inject
MainPresenter presenter;
AppComponent component;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
component = DaggerAppComponent
.builder()
.contextModule(new ContextModule(this))
.build();
component.inject(this);
}
AppModule
@Module
public abstract class AppModule {
@Binds
abstract Repository bindRepository(SharedPrefsRepository prefs);
@Binds
abstract MainPresenterListener listener(MainPresenterListener mListener);
@Provides
static SharedPreferences prefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
}
上下文模块
@Module
public class ContextModule {
private Context context;
public ContextModule(Context context) {
this.context = context;
}
@Provides
Context getContext() {
return context;
}
}
AppComponent
@Component (modules = {AppModule.class, ContextModule.class})
public interface AppComponent {
void inject(MainActivity activity);
}
以最简单的形式(并假设 Context
已经是您的依赖关系图的一部分),然后在您的模块中:
@Provides static SharedPreferences prefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
在您的 Presenter 中:
class Presenter {
private final SharedPreferences prefs;
@Inject
Presenter(SharedPreferences prefs) {
this.prefs = prefs;
}
}
不过,您还可以用它做更多的事情。例如,您可以将 Presenter
的范围限定为 View
的生命周期(即 Activity
或 Fragment
)。此外,最纯粹形式的 "Presenter" 应该对 Android 组件一无所知,因此您可能想要抽象出您自己的 API 背后的 SharedPreferences
。
编辑: 下面是一个示例,说明如何抽象化数据持久性,以便 Presenter 可以保持对 Android 组件的感知:
创建一个合适的接口(这只是持久化和 returns 字符串,因此相应地修改它):
interface Repository {
String read();
void write(String value);
}
创建此 interface
的实例,委托给 SharedPreferences
:
class SharedPrefsRespository implements Repository {
private static final String KEY = "a_key";
private final SharedPreferences prefs;
@Inject
SharedPrefsRepository(SharedPreferences prefs) {
this.prefs = prefs;
}
@Override
String read() {
return prefs.getString(KEY, "");
}
@Override
void write(String value) {
prefs.edit()
.putString(KEY, value == null ? "" : value)
.apply();
}
}
通过将以下内容添加到您的模块(确保您的模块是 abstract
)来告诉 Dagger Repository
的这个实现是您想要使用的那个:
@Binds abstract Repository repository(SharedPrefsRepository prefs);
在你的 Presenter
中,注入 Repository
而不是 SharedPreferences
:
class Presenter {
private final Repository repo;
private View view;
@Inject
Presenter(Repository repo) {
this.repo = repo;
}
void attach(View view) {
this.view = view;
showUserName();
}
//Example of how you might use this repo on something you want to persist
//Imagine a user has entered their username and clicked save...
void onSaveUserName(String username) {
repo.write(username);
}
private void showUserName() {
view.showUsername(repo.read());
}
}