我需要在模型中使用活动的Context,同时在android中使用MVP来获取所有已安装的应用程序的列表.访问上下文的正确方法是什么,或者在遵循MVP模式时实现相同的任何替代方法.
这是课程:
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);
}
Run Code Online (Sandbox Code Playgroud)
}
公共类MainPresenter扩展BasePresenter {
MainModel model;
public void onSendButtonClick(){
model.getListOfAllApps();
}
@Override
public void addView(MainView view) {
super.addView(view);
model=new MainModel();
}
Run Code Online (Sandbox Code Playgroud)
}
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);
}
Run Code Online (Sandbox Code Playgroud)
}
在getPackageManager().queryIntentActivities(mainIntent,0).如何执行此操作,因为这里没有任何上下文.
Jah*_*old 23
我在这里回答了一个类似的问题,你也可以看看.我会详细说明我认为你可以解决这个特殊问题.
使用Application类中的静态上下文
这种方法可行,但我不喜欢它.它使测试更加困难并将代码耦合在一起.
public class App extends Application {
private static Context context;
public static Context getContext() {
return context;
}
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们已经解决了这个问题,让我们看一些更好的选择.
在活动中执行此操作
所以你的Activity实现了你的View.它可能也会做一些Anrdoidy事情,例如onActivityResult.将Android代码保存在Activity中并通过View界面访问它是有争议的:
public interface MainView {
List<String> getListOfAllApps();
}
Run Code Online (Sandbox Code Playgroud)
活动:
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;
}
//..
}
Run Code Online (Sandbox Code Playgroud)
主持人:
public class MainPresenter extends BasePresenter {
public void onSendButtonClick(){
view.getListOfAllApps();
}
}
Run Code Online (Sandbox Code Playgroud)
在单独的类中抽象细节
虽然最后一个选项没有违反MVP的规则,但是感觉不太正确,因为获取包列表并不是真正的View操作.我首选的选项是隐藏在接口/类后面使用Context.
创建一个类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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在让Presenter将其作为构造函数参数:
public class MainPresenter extends BasePresenter {
private PackageModel packageModel;
public MainPresenter(PackageModel packageModel) {
this.packageModel = packageModel;
}
public void onSendButtonClick(){
packageModel.getListOfAllApps();
}
}
Run Code Online (Sandbox Code Playgroud)
最后在你的活动中:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,Context的使用对于Presenter是隐藏的,它可以在不知道Android的情况下继续使用.这称为构造函数注入.如果您正在使用依赖注入框架,它可以为您构建所有依赖项.
如果你想,你可以为PackageModel创建一个接口,但我认为这不是必要的,因为像Mockito这样的模拟框架可以在不使用接口的情况下创建存根.
| 归档时间: |
|
| 查看次数: |
12751 次 |
| 最近记录: |