Можно ли переключить Wi-Fi-сети в Appium?

Это не имеет никакого отношения к циклам.

Это поведение срабатывает, потому что вы используете лямбда-выражение () => variable * 2, где внешняя область variable фактически не определена во внутренней области лямбда.

Лямбда-выражения (в C # 3 +, а также анонимные методы в C # 2) по-прежнему создают реальные методы. Передача переменных этим методам связана с некоторыми дилеммами (передать по значению? Pass по ссылке? C # идет по ссылке - но это открывает еще одну проблему, когда ссылка может пережить реальную переменную). Что C # для решения всех этих дилемм заключается в создании нового вспомогательного класса («замыкание») с полями, соответствующими локальным переменным, используемым в лямбда-выражениях, и методам, соответствующим фактическим лямбда-методам. Любые изменения в variable в вашем коде фактически преобразуются для изменения в этом ClosureClass.variable

. Таким образом, ваш цикл while обновляет ClosureClass.variable до тех пор, пока он не достигнет 10, тогда вы для циклов выполняете действия, которые все работают на одном и том же ClosureClass.variable.

Чтобы получить ожидаемый результат, вам необходимо создать разделение между переменной цикла и переменной, которая закрывается. Вы можете сделать это, введя другую переменную, то есть:

List<Func<int>> actions = new List<Func<int>>();
int variable = 0;
while (variable < 5)
{
    var t = variable; // now t will be closured (i.e. replaced by a field in the new class)
    actions.Add(() => t * 2);
    ++variable; // changing variable won't affect the closured variable t
}
foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}

Вы также можете переместить замыкание на другой метод для создания этого разделения:

List<Func<int>> actions = new List<Func<int>>();

int variable = 0;
while (variable < 5)
{
    actions.Add(Mult(variable));
    ++variable;
}

foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}

Вы можете реализовать Mult как лямбда-выражение (неявное замыкание)

static Func<int> Mult(int i)
{
    return () => i * 2;
}

или с фактическим вспомогательным классом:

public class Helper
{
    public int _i;
    public Helper(int i)
    {
        _i = i;
    }
    public int Method()
    {
        return _i * 2;
    }
}

static Func<int> Mult(int i)
{
    Helper help = new Helper(i);
    return help.Method;
}

В любом случае «Closures» не являются концепцией, связанной с циклами, но скорее, к анонимным методам / лямбда-выражениям используют локальные переменные с областью - хотя некоторые неосторожное использование циклов демонстрируют закрытие ловушек.

0
задан Suban unique 13 July 2018 в 07:49
поделиться

1 ответ

Привет, я использую этот метод, потому что Appium не одобрял их переключатель для Wi-Fi, и я создал свое собственное переопределение через консоль с помощью команд из adb. Он работает для меня, поэтому попробуйте использовать

public synchronized boolean wifiSetup(String udid, boolean flg) {
    synchronized (this) {
        String flgEnabled = (flg) ? "enable" : "disable";


        List<String> output = Console.runProcess(false, "adb -s " + udid + " shell am broadcast -a io.appium.settings.wifi --es setstatus " + flgEnabled);
        for (String line : output) {
            System.err.println(line);
            if (line.equalsIgnoreCase("Broadcast completed: result=-1"))
                return true;
        }
        return false;
    }

}

для отключения:

wifiSetup("xxxUDIDfromAndroid", false); 

использование для включения:

wifiSetup("xxxUDIDfromAndroid", true); 

И вот часть для вызова консоли:

public class Console {
    private static final String[] WIN_RUNTIME = { "cmd.exe", "/C" };
    private static final String[] OS_LINUX_RUNTIME = { "/bin/bash", "-l", "-c" };

    private Console() {

    }

    private static <T> T[] concat(T[] first, T[] second) {
        T[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

    @SuppressWarnings({ "hiding"})
    private static <String> String[] concatStr(String[] first, String[] second) {
        String[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }



    public static List<String> runProcess(boolean isWin, String... command) {           
        String[] allCommand = null;
        try {
            if (isWin) {
                allCommand = concat(WIN_RUNTIME, command);
            } else {
                allCommand = concat(OS_LINUX_RUNTIME, command);
            }
            ProcessBuilder pb = new ProcessBuilder(allCommand);
            pb.redirectErrorStream(true);
            Process p = pb.start();
            p.waitFor();
            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String _temp = null;
            List<String> line = new ArrayList<String>();
            while ((_temp = in.readLine()) != null) {
//              system.out.println("temp line: " + _temp);
                line.add(_temp);
            }
//          system.out.println("result after command: " + line);
            return line;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

Надеюсь, это поможет,

0
ответ дан Kovacic 17 August 2018 в 13:27
поделиться
  • 1
    Спасибо за ответ. Я могу включить / выключить wifi с помощью driver.toggleWifi (). Но мне нужно переключать между различными сетями Wi-Fi, доступными с использованием ssid имени и пароля wifi. – Suban unique 13 July 2018 в 07:53
Другие вопросы по тегам:

Похожие вопросы: