Android MVP,获取剪贴板数据时相同的旧上下文问题?



所以我需要在演示器中获取剪贴板数据。这意味着我需要context.不幸的是,如果依赖注入是唯一的标准方法,我对依赖注入一无所知。 我研究了一些解决方案,但它们被认为是错误的解决方案。

public class MainActivityPresenter implements MainActivityInterfaces.MainToPresenter {
MainActivityInterfaces.PresenterToMain main;

public MainActivityPresenter (MainActivityInterfaces.PresenterToMain main) {
this.main = main;
}

@Override
public void processUrl() {
String url = Utils.getClipboardData(context);
if (url.isEmpty()) {
} else {
}
}

}

这是 Utils 类中的方法

public static String getClipboardData (Context context) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
android.text.ClipboardManager cm = (android.text.ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
String result = cm.getText().toString();
return result==null?"":result;
} else {
ClipboardManager cm = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
ClipData.Item item = cm.getPrimaryClip().getItemAt(0);
if (item != null)
return item.getText().toString();
else
return "";
}
}

正确的方式,演示者不应该知道任何特定的Android元素,ClipboardManagerContext(即:它应该是纯Java)。剪贴板逻辑应该在View内进行,并将所需的任何内容返回给Presenter

丑陋的方式,如果你想继续这个设计,processUrl应该采用上下文,大概这个方法是从视图中调用的?所以这就是可以提供上下文的地方。

@Override
public void processUrl(Context context) {
String url = Utils.getClipboardData(context);
if (url.isEmpty()) {
} else {
}
}

在视图中:

presenter.processUrl(getApplicationContext());

另一种解决方案是请求从演示者到视图的上下文:

@Override
public void processUrl() {
final Context context = view.getContext();
String url = Utils.getClipboardData(context);
if (url.isEmpty()) {
} else {
}
}
//In the view
void Context getContext() {
return getApplicationContext();
}

在 MVP 中,当视图将事件传播到演示者时,将某些信息发送给演示者是很常见的。在您的情况下,按如下方式重命名您的方法是非常合乎逻辑的:

@Override
public void processUrl(String url) {
if (url.isEmpty()) {
} else {
}
}

这样,视图将负责将信息与事件一起传播。而且你还在演示者中保持对视图(Android事物)特性的无知,这在MVP模式中非常重要。

祝你好运!

我知道这对你的问题没有帮助。但除了 MVP 之外,MVVM 是健壮和干净的模式,不需要像 MVP 那样多的样板代码,所以如果你仍然处于开始一个项目并决定或架构的阶段,我可以,作为一个专业的 Android 开发人员,只推荐 MVVM。由于 LiveData 位于 ViewModel 中,MVVM 还会执行状态保存,因此您不必通过保存的实例捆绑包费力地向演示器添加功能。

如果您需要 DI 以便将上下文注入演示器(这是不可取的,上下文不应该理想地进入演示器,但有时会发生这种情况,因为很难创建在演示器中执行上下文所需工作的实体),并且您是新手且没有 DI 经验,那么使用 Java,您需要使用 Dagger 2, 它有一个陡峭的学习曲线。切换到 Kotlin 然后使用 Koin 可能比学习 Dagger 2 更容易,但如果您喜欢它,请尝试一下。无论如何,在专业项目中都必须有 DI。

如果不想使用 DI 将上下文传递到表示器,请将其传递到构造函数中。我想活动或片段是您初始化演示器(创建它的新实例)以及将"视图"概念传递给演示者的地方。如果您需要演示器中的上下文(同样,这不是最好的做法,但好吧,您是我理解的模式新手),那么只需将其传递到构造函数中并在演示器中进行设置即可。

在演示器中使用上下文不是一个好主意。

如果我需要上下文怎么办?

好吧,摆脱它。在这种情况下,你应该问问自己为什么需要上下文。例如,您可能需要上下文来访问共享首选项或资源。但您不应该在表示器中执行此操作:您应该访问视图中的资源和模型中的首选项。这只是两个简单的例子,但我敢打赌,大多数时候这只是一个错误的责任问题。

您可以从视图在构造函数中传递 url。

public class MainActivityPresenter implements MainActivityInterfaces.MainToPresenter {
MainActivityInterfaces.PresenterToMain main;
private String mUrl;
public MainActivityPresenter (MainActivityInterfaces.PresenterToMain main, String mUrl) {
this.main = main;
this.mUrl = mUrl;
}
@Override
public void processUrl() {
if (mUrl.isEmpty()) {
} else {
}
}
interface SomeView {
void onUrlProcessed();
}
}

在您的主活动中:

class MainActivity {
String url = Utils.getClipboardData(getContext());
}

您可以参考其他答案 此处 .

演示者了解活动/上下文在 MVP 模式中是否是一个坏主意?

Android MVP:在演示器中安全使用上下文

最新更新