如何使用Dagger和MVP实现共享首选项,大多数教程都是在Activity中编写共享首选项或为演示者提供上下文。
我需要的是看例子:
presenter
以获得sharedPreference
无需使用Context
。module
的外观。Component
或每个地方致电Application
提供上下文的活动。===更新===
正如 PPartisan 在他的回答中提到的那样,我不应该在sharedPreference
中加入 Presenter
。
那么我该如何在API后面抽象 SharedPreferences
===更新2 ===
感谢您的回答 PPartisan ,它确实很好用,请您检查一下我的代码是否完美,或者是否需要任何调整。
MainActivity
@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);
}
}
ContextModule
@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);
}
答案 0 :(得分:2)
以最简单的形式(并假设Context
已成为依赖图的一部分),然后在模块中:
@Provides static SharedPreferences prefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
在演示者中:
class Presenter {
private final SharedPreferences prefs;
@Inject
Presenter(SharedPreferences prefs) {
this.prefs = prefs;
}
}
但是,您可以做更多的事情。例如,您可以将Presenter
的范围限定为View
的生命周期(即Activity
或Fragment
)。另外,“ Presenter”以其最纯粹的形式应该对Android组件一无所知,因此您可能希望将SharedPreferences
抽象到您自己的API后面。
编辑:下面是一个示例,该示例说明了如何抽象化数据持久性,以便Presenter可以不了解Android组件:
创建一个合适的接口(该接口会持久保存并返回字符串,因此请相应地对其进行修改):
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();
}
}
告诉Dagger,您想通过将以下内容添加到模块中来确保使用Repository
的这种实现(确保您的模块为abstract
):
@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());
}
}