gpt4 book ai didi

android - MVP 模型中需要上下文

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:54:58 26 4
gpt4 key购买 nike

我需要在 android 中使用 MVP 时使用模型中的 Activity 上下文来获取所有已安装应用程序的列表。访问上下文的正确方法是什么,或者在遵循 MVP 模式时实现相同目的的任何替代方法是什么.

这里是类:

主 Activity .java

public class MainActivity extends BaseActivity
implements MainView,View.OnClickListener {

private MainPresenter mPresenter;
private Button sendButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
createPresenter();
}

private void init(){
sendButton= (Button) findViewById(R.id.button_send);
sendButton.setOnClickListener(this);
}

private void createPresenter() {
mPresenter=new MainPresenter();
mPresenter.addView(this);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.button_send:
mPresenter.onSendButtonClick();
break;
}
}

@Override
public void openOptionsActivity() {
Intent intent=new Intent(this,OptionsActivity.class);
startActivity(intent);
}
}

主Presenter.java

公共(public)类 MainPresenter 扩展 BasePresenter {
    MainModel model;

public void onSendButtonClick() {
model.getListOfAllApps();
}

@Override
public void addView(MainView view) {
super.addView(view);
model = new MainModel();
}

}

主模型.java

public class MainModel {

public void getListOfAllApps(){
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List pkgAppsList = getPackageManager().queryIntentActivities(mainIntent, 0);

}

}

getPackageManager().queryIntentActivities(mainIntent, 0) 中有问题。由于此处没有任何上下文,因此如何处理。

最佳答案

我回答过类似的问题here您可能也想看看。不过,我将详细说明我认为您可以如何解决这个特定问题。

使用来自 Application 类的静态上下文

这个方法可行,但我不喜欢它。它使测试更加困难,并将您的代码耦合在一起。

public class App extends Application {

private static Context context;

public static Context getContext() {
return context;
}

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

然后在您的 MainModel 中:

public class MainModel {

public List<String> getListOfAllApps(){

final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> pkgAppsList = App.getContext().getPackageManager().queryIntentActivities(mainIntent, 0);

List<String> results = new ArrayList<>();
for (ResolveInfo app : pkgAppsList) {
results.add(app.resolvePackageName);
}
return results;
}
}

现在我们已经解决了这个问题,让我们看看一些更好的选择。

在 Activity 中做

因此,您的 Activity 实现了您的 View。它可能也在做一些 Anrdoidy 的事情,比如 onActivityResult。将 Android 代码保留在 Activity 中并仅通过 View 界面访问它是有争议的:

public interface MainView {

List<String> getListOfAllApps();
}

Activity :

public class MainActivity extends BaseActivity implements MainView {

//..

@Override
public List<String> getListOfAllApps(){

final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> pkgAppsList = getPackageManager().queryIntentActivities(mainIntent, 0);

List<String> results = new ArrayList<>();
for (ResolveInfo app : pkgAppsList) {
results.add(app.resolvePackageName);
}
return results;
}

//..
}

和演示者:

public class MainPresenter extends BasePresenter {

public void onSendButtonClick(){

view.getListOfAllApps();
}
}

在单独的类中抽象细节

虽然最后一个选项没有违反 MVP 的规则,但感觉不太正确,因为获取包列表不是真正的 View 操作。我的首选选项是将 Context 的使用隐藏在接口(interface)/类后面。

创建一个类 PackageModel(或您喜欢的任何名称):

public class PackageModel {

private Context context;

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

public List<String> getListOfAllApps(){

final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities(mainIntent, 0);

List<String> results = new ArrayList<>();
for (ResolveInfo app : pkgAppsList) {
results.add(app.resolvePackageName);
}
return results;
}
}

现在让您的 Presenter 要求它作为构造函数参数:

public class MainPresenter extends BasePresenter {

private PackageModel packageModel;

public MainPresenter(PackageModel packageModel) {
this.packageModel = packageModel;
}

public void onSendButtonClick(){

packageModel.getListOfAllApps();
}
}

最后在您的 Activity 中:

public class MainActivity extends BaseActivity implements MainView {

private MainPresenter presenter;

private void createPresenter() {

PackageModel packageModel = new PackageModel(this);
presenter = new MainPresenter(packageModel);
presenter.addView(this);
}
}

现在 Context 的使用对 Presenter 是隐藏的,它可以在不了解 Android 的情况下进行。这称为构造函数注入(inject)。如果您使用的是依赖项注入(inject)框架,它可以为您构建所有依赖项。

如果您愿意,您可以为 PackageModel 创建一个接口(interface),但我认为这不是真正必要的,因为像 Mockito 这样的模拟框架可以在不使用接口(interface)的情况下创建 stub 。

关于android - MVP 模型中需要上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39100105/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com