You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在MVP模式下如何将上下文传递给仓库?

在MVP模式下向仓库传递Context的几种方案

嘿,这个问题问到点子上了——Android里不管是操作SharedPreferences、本地数据库还是文件,都绕不开Context,在MVP架构里怎么优雅又安全地把它传到仓库层,我给你分享几个实用的思路:

1. 沿着MVP调用链手动传递(适合小型项目)

按照你目前的代码结构,Activity已经把自身的Context传给了Presenter,其实可以顺着这条链往下传:从Activity到Model,再由Model把Context传给仓库。不过这里有个关键细节:一定要传递ApplicationContext,而不是Activity的实例,不然很容易因为仓库持有Activity的引用导致内存泄漏。

举个代码例子:

Activity层

// 创建Presenter时,把ApplicationContext传给Model
MainPresenter mainPresenter = new MainPresenter(this, new MainModel(getApplicationContext()));

Model层

public class MainModel {
    private UserRepository userRepository;

    // Model接收ApplicationContext,再传给仓库
    public MainModel(Context appContext) {
        userRepository = new UserRepository(appContext);
    }

    // 业务方法中调用仓库完成数据操作
    public void saveUserInfo(String username) {
        userRepository.saveUsernameToPrefs(username);
    }
}

仓库层

public class UserRepository {
    private Context appContext;

    public UserRepository(Context appContext) {
        this.appContext = appContext;
    }

    public void saveUsernameToPrefs(String username) {
        SharedPreferences prefs = appContext.getSharedPreferences("UserPrefs", Context.MODE_PRIVATE);
        prefs.edit().putString("username", username).apply();
    }
}

2. 用依赖注入实现解耦(中大型项目首选)

如果你的项目规模较大,手动传递Context会让代码变得繁琐且耦合度高,这时候用依赖注入框架(比如Hilt、Dagger)会更优雅。这些框架可以帮你自动管理ApplicationContext的传递,不需要手动在各个层之间传参。

比如用Hilt的例子:

仓库层

public class UserRepository {
    private Context appContext;

    // 通过Hilt注入ApplicationContext
    @Inject
    public UserRepository(@ApplicationContext Context appContext) {
        this.appContext = appContext;
    }

    public void saveUsernameToPrefs(String username) {
        SharedPreferences prefs = appContext.getSharedPreferences("UserPrefs", Context.MODE_PRIVATE);
        prefs.edit().putString("username", username).apply();
    }
}

Model层

public class MainModel {
    private UserRepository userRepository;

    // 注入仓库实例,不用手动传Context
    @Inject
    public MainModel(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // 业务方法调用仓库
    public void saveUserInfo(String username) {
        userRepository.saveUsernameToPrefs(username);
    }
}

Activity层

// Hilt会自动注入Presenter和Model,不用手动传递Context
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
    @Inject
    MainPresenter mainPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 直接使用Presenter即可
        mainPresenter.saveUser("Taha");
    }
}

3. 通过自定义Application获取全局Context(简单但要谨慎使用)

如果你的仓库是全局通用的,也可以通过自定义Application类来提供全局的ApplicationContext,这样仓库可以直接获取,不需要层层传递。

自定义Application类

public class MyApp extends Application {
    private static Context appContext;

    @Override
    public void onCreate() {
        super.onCreate();
        appContext = getApplicationContext();
    }

    public static Context getAppContext() {
        return appContext;
    }
}

记得在AndroidManifest.xml里指定这个Application:

<application
    android:name=".MyApp"
    ...>
</application>

仓库层直接使用

public class UserRepository {
    public void saveUsernameToPrefs(String username) {
        Context appContext = MyApp.getAppContext();
        SharedPreferences prefs = appContext.getSharedPreferences("UserPrefs", Context.MODE_PRIVATE);
        prefs.edit().putString("username", username).apply();
    }
}

这个方法简单快捷,但要注意不要滥用静态Context——不过这里用的是ApplicationContext,不会持有Activity引用,所以是安全的。


总结一下:如果是小型项目,手动传递ApplicationContext足够用;中大型项目优先考虑依赖注入,能大幅降低耦合度;自定义Application的方式适合全局通用的仓库场景。不管用哪种方式,核心原则都是避免持有Activity的Context,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Taha Kirmani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:45:02