Как мне синхронизировать этот код, чтобы ждать AsyncTask - PullRequest
0 голосов
/ 27 сентября 2019

Я делаю приложение с Android Studio.Я до сих пор создал фазы регистрации и входа.

При регистрации наиболее важными проверками являются то, что пользователь, почта и номер телефона должны быть уникальными (по сравнению с незначительными проверками, такими как регулярное выражение), на этапе входа в систему проверьте, что пользователь существует, а затем проверьте, чтопароль такой же, как у меня в базе данных, и прежде всего, что пользователь не заблокирован (число от 0 до 3, чтобы сообщить об ошибках, допущенных при вводе пропуска).

Что происходит?Что при вводе данных, как для входа в систему, так и для регистрации, и я нажимаю кнопку, чтобы запустить проверки, которые подтверждают доступ / регистрацию (выполнить все проверки), все проверки должны быть выполнены, но вся функция дает сбой.Позвольте привести пример:

первое нажатие: проверка имени пользователя (без результата),

второе нажатие: проверка имени пользователя (с результатом) и проверка телефона (без результата)

третье нажатие: проверить имя пользователя (с результатом) и проверить телефон (с результатом) и проверить почту (без результата)

четвертое нажатие: проверить имя пользователя (с результатом) и проверить телефон (с результатом) и проверить почту (с результатом), все в порядке!

Затем функции выполняются вместе, отвечая пользователю результата продукта (например, неправильный номер телефона).

Это происходит только при наличии AsyncTask.Я говорю, что для каждого из них я установил 7-секундный таймер для соединения, но каждый «первый раз» не длится полсекунды (ProgressDialog появляется и исчезает, а Toast не запрограммирован, в то время как в следующих исполнениях ProgressDialog длитсявремя установлено и правильно реагирует на результат операции).

Активность - Нажмите кнопку

public synchronized void provapost(View v) {

    boolean ci = controllointernet(), cs = false, cn = false, cm = false, ct = false, cp = false, cname = false, cc = false, cl = false, cd = false;

    if (ci) {
        cn = controllonickname();
    } else...

    if (ci && cn) {
        cp = controllopassword(); //works correctly, no asynctask, all Java instructions
    } else...

    if (ci && cn && cp) {
        ct = controllotelefono();
    } else...

   if (ci && cn && cp && ct) {
        cm = controllomail();
    } else...

controllonickname Метод (аналогично controllotelefono и controllomail)

String u = user.getText().toString();
ControlloUsername task = new ControlloUsername(this);
task.execute(u);
task.setOnFinishListener(new ControlloUsername.onFinishListener() {
       @Override
       public void onFinish(String res) {
           // The task has finished and you can now use the result
           if (res.contains("xxx")) {...
              ...
              ...
       ...}
        });

ControlloUsername (всегда аналогично другим Asynctasks)

public class ControlloUsername extends AsyncTask<String, Void, String> {

// TODO Auto-generated method stub
Context context;
ProgressDialog a;
onFinishListener mListener; // Create a variable for your interface

// Define the interface & callbacks
public interface onFinishListener{
    // Replace 'variableType' with the appropriate type for your result
    void onFinish(String myResult);
}

public void setOnFinishListener(onFinishListener l){
    mListener = l;
}

public ControlloUsername(Context ct) {
    // TODO Auto-generated constructor stub
    context = ct;
}

@Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    a=new ProgressDialog(context);
    a.setTitle("Send");
    a.setMessage("Sending..Please wait");
    a.show();
}

@Override
protected void onPostExecute(String result) { //sync
    if(mListener != null){
        mListener.onFinish(result);
    }
    a.dismiss();
}

@Override
protected void onProgressUpdate(Void... values) {
    a.show();
}

@Override
protected String doInBackground(String... params) { //sync
    // TODO Auto-generated method stub

    String username = params[0];
    String login_url = Connector.db + "script/usercontrol.php";
    String resultado = "";

    URL u = null;
    try {
        u = new URL(login_url);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    HttpURLConnection http = null;
    try {
        http = (HttpURLConnection) u.openConnection();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        http.setRequestMethod("POST");
    } catch (ProtocolException e) {
        Writer writer = new StringWriter();
        e.printStackTrace(new PrintWriter(writer));
        resultado = writer.toString();
    }
        http.setDoInput(true);
        http.setDoOutput(true);



    try {
        http.setConnectTimeout(5000);
        OutputStream out = http.getOutputStream();
        BufferedWriter bf = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
        String post_data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8");
        bf.write(post_data);
        bf.flush();
        bf.close();
        out.close();
        InputStream in = http.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in, "iso-8859-1"));
        String result = "";
        String line = "";
        while ((line = br.readLine()) != null) {
            result += line;
        }
        bf.close();
        in.close();
        http.disconnect();
        return result;
    } catch (ConnectException e) {
        ...
}
...
}

VIDEO: https://youtu.be/BLIp7YmiphM

В примеревидео, я сначала проверяю, что пользователь существует, затем я проверяю пароль, и в случае, если он неправильный, я уменьшаю количество возможных ошибок, пока не заблокирую учетную запись до «четвертой ошибки» (которая является седьмой),Первые три раза я нажимаю, я запускаю userControl / passControl / refreshErrors-AsyncTasks (примерно в следующие несколько раз, я думаю, у меня проблемы с синхронизацией между методами, которые принимают и помещают данные в БД).

IУ меня были проблемы раньше, потому что AsyncTasks заблокировали пользовательский интерфейс, поэтому я использовал этот альтернативный метод.Может ли это быть неиспользование и не реализация OnPostExecute?

Я выполнил отладку, чтобы увидеть, были ли пропущены какие-либо шаги, но на самом деле все сделано правильно, и, похоже, он также возвращает результатв UiThread, который не работает и не показывает тост.Всякий раз, когда AsyncTask «не работает», соответствующий ProgressDialog длится очень мало времени, только тогда, кажется, он длится столько времени, сколько потребуется.Я даже не могу дождаться ответа, потому что они предложили использовать FinishListener для предотвращения сбоя UiThread.Я не знаю, должен ли я в этот момент использовать семафор, чтобы ждать и перейти к завершенной проверке, но я не знаю, где он должен быть вставлен и как его применить.У меня такое впечатление, что «первый раз» не удается подключиться к серверу: на самом деле я установил таймер на 7 секунд, но, как я уже сказал, каждый «первый раз» AsyncTask длится очень долго.мало, появляется и исчезает менее чем за секунду.Только позже это работает правильно.

Что это может быть?Большое спасибо:)

НОВАЯ ИНФОРМАЦИЯ: Я заметил, что функция, соответствующая кнопке для регистрации, в Регистрационной активности, продолжает свое выполнение без ожиданияответ функции checkusername (см. класс Activity).Затем он продолжается в первый раз, учитывая, что глобальная переменная (которая изменится на true, если имя пользователя доступно), имеет значение false, а второй раз, учитывая, что переменная является истинной (очевидно, она была истинной в предыдущий раз).Как синхронизировать и дождаться ответа и действительного значения?

2019-09-28 06: 05: 10.269 8309-8309 / oneforyou.jep.oneforyou D / TEST: переменнаяfalse

2019-09-28 06: 05: 10.317 8309-8431 / oneforyou.jep.oneforyou D / TEST: псевдоним доступен!

2019-09-28 06: 05: 13.783 8309-8309 / oneforyou.jep.oneforyou D / TEST: переменная true

2019-09-28 06: 05: 13.836 8309-8430 / oneforyou.jep.oneforyou D / TEST: псевдоним недоступен!

Здесь результат в порядке, но имя пользователя было изменено на недоступное ... Как видите, истинное значение глобальной переменной наследуется от предыдущего выполнения, а не от текущего.Я думаю, что это проблема синхронизации или тип переменной (volatile, static, final ...). controllonickname производит значение, следующие инструкции потребляют эту информацию. Я не понимаю, почему он это делает, я искренен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...