简体   繁体   English

存在startActivityForResult调用的Android程序流控制

[英]Android program flow control in presence of startActivityForResult call

The program in question, when run on Android, controls slave Bluetooth (BT) devices. 有问题的程序在Android上运行时,将控制从属蓝牙(BT)设备。 It has few buttons which enable different functions of the peer devices. 它只有很少的按钮可以启用对等设备的不同功能。

Bluetooth is not enabled by default on the Android device, and the connection is established for short periods after button(s) click. 默认情况下,Android设备上未启用蓝牙功能,并且在单击按钮后的短时间内建立了连接。

So, the flow after each button click is: 因此,单击每个按钮后的流程为:

  1. ensure BT enabled ( startActivityForResult() with BT enable intent if not) 确保启用了BT startActivityForResult()如果未启用BT,则使用startActivityForResult()启用意图)
  2. connect to the remote device 连接到远程设备
  3. enable some function of the remote device 启用远程设备的某些功能
  4. disconnect from the device 与设备断开连接

My issue is that if BT is not enabled, then a call to startActivityForResult() in #1 "breaks" the program flow. 我的问题是,如果未启用BT,则在#1中对startActivityForResult()的调用会“中断”程序流程。 Later, when onActivityResult() is called, I want to resume the flow from the point where it was "breaked". 稍后,当调用onActivityResult()时,我想从“中断”点开始恢复流程。

For that purpose I defined additional member field and few constants and used them in onActivityResult() : 为此,我定义了其他成员字段和一些常量,并在onActivityResult()使用了它们:

private int mRerunMethodIndex = 0;
private static final int RERUN_METHOD1 = 1;
private static final inr RERUN_METHOD2 = 2;
...
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_ENABLE_BT:
            if (resultCode == Activity.RESULT_OK) {
                int rerunMethodIndex = mRerunMethodIndex;
                mRerunMethodIndex = 0;
                switch (rerunMethodIndex ) {
                    case (RERUN_METHOD1):
                        method1();
                        break;
                    case (RERUN_METHOD2):
                        method2();
                        break;
                    // ... the same for other cases
                }
            }
            break;    
        default:
            break;
    }
}

Now, one more complication: onActivityResult() will be called before activity's onResume() . 现在,还有一个复杂的问题: onActivityResult()将在活动的onResume()之前调用。 This will matter if any of the methodX() need to alter views hierarchy. 如果任何methodX()需要更改视图层次结构,这都将很重要。 In my case these methods replace some Fragments, and if this operation is executed from onActivityResult() then exception is thrown. 在我的情况下,这些方法替换了一些Fragments,如果从onActivityResult()执行此操作,则会引发异常。

In order to resolve this additional issue, the ugly switch from onActivityResult() migrates to onPostResume() . 为了解决此其他问题,从onActivityResult()的难看的switch迁移到onPostResume()

The approach described above works, but it is one of the ugliest pieces of code I've ever written: methodX() "registers" itself for "rerun" by assigning RERUN_METHOD_X constant to mRerunMethodIndex , onActivityResults() sets some "rerun flag" after BT is enabled, onPostResume() checks the flag, clears this flag, clears mRerunMethodIndex and reruns the appropriate methodX() . 上面描述的方法有效,但是它是我编写过的最丑的代码之一: methodX()通过将RERUN_METHOD_X常量分配给RERUN_METHOD_X来为“重新运行”自身注册“ mRerunMethodIndexonActivityResults()在之后设置一些“重新运行标志”启用BT, onPostResume()检查该标志,清除此标志,清除mRerunMethodIndex并重新运行适当的methodX()

Is there a more elegant approach (preferably confined to 1 or 2 methods)? 有没有更优雅的方法(最好限于一种或两种方法)?

You could use runnable to organize your workflow without using step constants. 您可以使用runnable来组织工作流,而无需使用步骤常数。 For example: 例如:

public void Runnable mMethod1 = new Runnable() {
    public void run() {
        // your code for method 1
    }
}

public void Runnable mMethod2 = new Runnable() {
    public void run() {
        // your code for method 2
    }
}

public void Runnable mMethod3 = new Runnable() {
    public void run() {
        // your code for method 3
    }
}

private void startMethod(Runnable method) {
    mCurrentMethod = method;
    method.run();
}

...

public vond onPostResume() {
    if (mCurrentMethod != null) {
        mCurrentMethod.run();
        mCurrentMethod = null;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM