gpt4 book ai didi

android - 如何用 MVP 实现 PhoneStateListener

转载 作者:行者123 更新时间:2023-11-29 02:31:59 30 4
gpt4 key购买 nike

我正在用 MVP 重构我的一个旧应用。我已经重构了大部分逻辑,现在我坚持使用以下逻辑。在我的一项 Activity 中,我实现了 PhoneStateLister,如下所示。

private class CallStateListener extends PhoneStateListener {

public void onCallStateChanged(int state, String incomingNumber) {

switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
deactivateSpeaker();
if (callCount == 0) {
doCall();
} else {
checkForHangUp();
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
checkAutoSpeaker();
break;
case TelephonyManager.CALL_STATE_RINGING:
break;
default:
break;
}
}

private void checkAutoSpeaker() {
if (preferenceManager.isAutoSpeaker()) activateSpeaker();
}

private void activateSpeaker() {
final Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
}
}, 1000);
}

private void deactivateSpeaker() {
audioManager.setMode(AudioManager.MODE_NORMAL); //Deactivate loudspeaker
}

}

我很难决定将此逻辑放在 MVP 中的什么位置。 Activity 应该处理这个 PhoneStateListener 还是 presenter 应该处理这个?请帮我解决问题。谢谢。

最佳答案

MVP 模式中设置listeners 总是有点棘手。我很确定您的问题没有“正确”“错误”的答案,因为这在很大程度上取决于您的个人喜好和架构风格。但正如我的一般规则,将尽可能多的业务逻辑转移到 presenter 并让其他一切(这也包括 listeners)尽可能地愚蠢总是明智的。

这就是为什么我建议您向您的listener 类添加一个interface 并在那里保留对presenter 的(弱)引用.在该示例中,listener 所做的唯一一件事就是监听状态变化,然后将信息转发给 presenter(信息在此处分发)。

public class CallStateListener extends PhoneStateListener {
private final WeakReference<CallStateListenerInterface> presenterInterface;
public CallStateListener(CallStateListenerInterface presenterInterface){
this.presenterInterface = new WeakReference<>(presenterInterface);
}
public void onCallStateChanged(int state, String incomingNumber){
presenterInterface.get().onCallStateListenerCallStateChanged(state, incomingNumber);
}
public interface CallStateListenerInterface {
void onCallStateListenerCallStateChanged(int state, String incomingNumber);
}
}

presenter 需要实现CallStateListenerInterface(当然)并在调用状态更改时处理所有业务逻辑。

public class myPresenter implements MVPInterface, CallStateListenerInterface {

/*your business logic*/

public void onCallStateListenerCallStateChanged(int state, String incomingNumber){
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
deactivateSpeaker();
if (callCount == 0) {
doCall();
} else {
checkForHangUp();
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
checkAutoSpeaker();
break;
case TelephonyManager.CALL_STATE_RINGING:
break;
default:
break;
}
}
}

从这里开始,所有需要与view 交互的东西都将被调用,但是将这些调用保持在简单的一行指令中,让所有复杂的事情留给presenter 来决定。

如果您不想为每个监听器类添加新的接口(interface),您也可以将整个MVPInterface 传递给CallStateChangedListener (并在您的契约(Contract)的中心位置声明所有内容)。

如果您以这种方式实现监听器,您将获得一个非常干净的架构,应该很容易测试。我希望这对您有所帮助,如果您有任何问题,请告诉我:)

小型替代实现:

正如评论者所指出的:在我最初的建议中,演示者从 TelephonyManager 类访问静态电话状态整数。这不是最干净的设计,因为演示者应该与任何 Android 特定代码完全分开。由于没有真正 super 干净的方法来解决这个问题,我只能建议从 TelephonyManager 状态到保存在演示者中的(自定义)电话状态的映射(或者更好:静态常量文件)。基本上这意味着 CallStateListener 中的 onCallStateChanged 应该看起来像这样:

public void onCallStateChanged(int state, String incomingNumber){
int stateValue = myPresenter.PRESENTER_CALL_STATE_IDLE;
if (state == TelephonyManager.CALL_STATE_RINGING){
stateValue = myPresenter.PRESENTER_CALL_STATE_RINGING;
} else if (state == TelephonyManager.CALL_STATE_OFFHOOK){
stateValue = myPresenter.PRESENTER_CALL_STATE_OFFHOOK;
}
presenterInterface.get().onCallStateListenerCallStateChanged(stateValue , incomingNumber);
}

通过此实现,您可以将 TelephonyManager 状态移出演示器并使用您自己定义的状态。(再一次:我真的不确定这是否值得付出努力,但我想至少提供替代方案)

关于android - 如何用 MVP 实现 PhoneStateListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49165710/

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