在 Presenter class 中访问 Actvity 的上下文是一个好习惯吗?如果没有,那么还有其他更好的方法吗?

Is it a good practice to access the Actvity's Context in the Presenter class? If no then is there any other better way to do it?

我是 Android MVP Architecture 的新手。据我研究,Presenter 应该不受任何 android 影响,例如:不要在 Presenter 中使用 getActivityContext。我编写了以下代码,其中 BasePresenter 是我将成为 using.The BaseView 接口的所有 Presenter class 的父级 class是所有 View classes 的父界面,BaseActivity class 是所有 Activity classes 的父界面 class。我有不止一条 activity,并且要求在我的所有 activity 中显示 Toast 条消息。所以我写了下面的代码如下。我不太确定使用演示者 class 的 getactivity 是否是一个好习惯。如果不是那么有人可以建议更好的方法吗?

BasePresenter class

public class BasePresenter<V extends BaseView> {
private V mView;
private Context mContext;

public void attachView(V view) {
    mView = view;
     mContext=mView.getActivity();
}

public void showToast(String msg) {
    Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
}

private Context getContext() {
    return mContext;
}

public void detachView() {
    mView = null;
}

} 

基础视图class

 public interface BaseView {
 AppCompatActivity getActivity();
 }

BaseActivityclass

public class BaseActivity extends AppCompatActivity {
public AppCompatActivity getActivity() {
    return this;
}

}

主要活动class

public class MainActivity extends BaseActivity implements MainView {
 MainPresenter basePresenter;
 @Override
protected void onStart() {
    super.onStart();
    basePresenter = new MainPresenter();
    basePresenter.attachView(this);
}

  // some more codes here

        switch (item.getItemId()) {
                case R.id.about:
                    basePresenter.showToast("About is Clicked");

                    break;
                case R.id.cart:
                    basePresenter.showToast("Cart is Clicked");

                    break;
                case R.id.favs:
                    basePresenter.showToast("Favs is Clicked");

                    break;
                case R.id.home:
                    basePresenter.showToast("Home is Clicked");

                    break;
            }
        }

吐司实际上在屏幕上可见。所以它不应该在演示者中。它应该从视图中触发。

这不是个好主意。您的 Presenter(基础或其他)不应该知道 Context、Activity、Toast 或任何其他基于 Android 的内容。

查看

  1. 展示东西。
  2. 处理用户输入并将其传递给 Presenter

主持人

  1. 决定如何处理用户输入。
  2. 从模型中收集数据。
  3. 告诉 View 做什么。

因此,对于单击按钮并显示 Toasts 的示例,您需要类似以下的设置:

查看界面

这就是 Presenter 与 View 对话的方式。它将由 Activity.

实施
public interface MainView {

    void showToast(String message);
}

主持人(基本和主要)

BasePresenter 几乎没有任何任务。只需在那里绑定 View 界面。请注意 MainPresenter 中的方法名称与 'click' 之类的名称不明确,以便将它们与视图实现分开。

public class BasePresenter<V> {

    protected V view;

    public void attachView(V view) {
        this.view = view;
    }
}

public class MainPresenter extends BasePresenter<MainView> {

    public void about() {
        view.showToast("About was clicked");
    }

    public void cart() {
        view.showToast("Cart was clicked");
    }
}

Activity

Activity实现了View接口。它负责将用户事件传递给 Presenter 并执行 Presenter 命令。

public class MainActivity extends AppCompatActivity implements MainView {

    private MainPresenter presenter;

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

        presenter = new MainPresenter();
        presenter.attachView(this);

        Button about = findViewById(R.id.button_about);
        about.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.about();
            }
        });

        Button cart = findViewById(R.id.button_cart);
        cart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.cart();
            }
        });
    }

    @Override
    public void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}

在此设置中,Presenter 不再了解 Android(根本没有从框架导入),您可以为其编写单元测试,它可以 运行 直接在没有 Android 依赖项的 JVM。