onPostExecute не вызывается в AsyncTask - PullRequest
0 голосов
/ 15 апреля 2020

У нас есть приложение android, работающее с использованием SDK 26. Я переписываю код для использования MVP (о котором я только что узнал).

Для некоторого контекста по моей проблеме, Вот классы, которые, я считаю, довольно стандартны для MVP:

LoginContract (представление интерфейса, интерфейс Presenter)

LoginActivity реализует LoginContract.View

LoginPresenter реализует LoginContract.Presenter

LoginModelWS

В основном проблема заключается в том, что метод onPostExecute в моем AsyncTask не является будучи призванным Эта проблема возникла с тех пор, как я реорганизовал logi c для создания экземпляра и вызова этой асинхронной задачи из Activity и в LoginModel. Asynctask выполняет SOAP вызов веб-службы на нашем сервере для проверки подлинности имени пользователя.

Поэтому я прочитал AsyncTasks и обнаружил, что это может быть вызвано множеством вещей в соответствии с правилами потоков, указанными в Класс AsyncTask:

  • Класс AsyncTask должен быть загружен в потоке пользовательского интерфейса.
  • Экземпляр задачи должен быть создан в потоке пользовательского интерфейса.
  • execute () должен быть вызванным в потоке пользовательского интерфейса.
  • , вызывающим метод doInBackground () напрямую

Я подтвердил, что мой код запускался в потоке пользовательского интерфейса, выполнив:

if (Looper.myLooper() == Looper.getMainLooper() ) // Then Print confirmation

Мой вопрос: почему не вызывается onPostExecute (), теперь я переместил код из Activity в модель?

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

Класс LoginPresenter

 public LoginPresenter(LoginContract.View mView, SharedPreferenceManager spm){
    this.mView = mView;
    mLoginWS = new LoginModel();
}
public void doLogin(String encodedBarcodeScan) {
    String[] userPass = getUserNameAndPassFromScanString(encodedBarcodeScan);
    if (userPass == null || userPass.length != 2){
        mView.showErrorWithBarcodeScan();
    }
    else {
        mLoginModel.doLogin(userPass[0], userPass[1]);
    }
}

Класс LoginContract

public interface LoginContract {

interface View {
    void showErrorWithBarcodeScan();
    void redirectToMainMenu();
    void showLoginError();
}

interface Presenter {
    void doLogin(String encodedBarcodeScan);
}

}

Класс LoginModel

    public String authenticateLogin(final String userName, final String password, final String url)
{
    authenticationResponse = null;
    ModelCRUDRequest request = WebServiceUtil.getModelCrudRequest();
    request.ADLoginRequest = WebServiceUtil.getADLoginRequest(userName, password);
    ModelADServiceSoapBinding binding = new ModelADServiceSoapBinding(new IServiceEvents() {

        @Override
        public void Starting()
        {
        }

        @Override
        public void Completed(OperationResult result) // THIS CODE IS NEVER REACHED
        {
            WindowTabData response = (WindowTabData) result.Result;
            if (response == null){
                authenticationResponse = WebServiceResponseMessage.CONNECTION_ERROR;
            }
            else if (response != null && response.Error != null && response.Error.length() > 0)
            {
                authenticationResponse = WebServiceResponseMessage.SERVER_ERROR + response.Error;
            }
            else
            {
                try
                {
                    if (response.NumRows > 0)
                    {
                        // successful login
                        authenticationResponse = WebServiceResponseMessage.LOGIN_AUTHENTICATED;
                    }
                    else
                    {
                        authenticationResponse = WebServiceResponseMessage.LOGIN_FAILED;
                    }
                }
                catch (Exception e)
                {
                    authenticationResponse = WebServiceResponseMessage.EXCEPTION + e.getMessage();
                }
            }
        }
    }, url);


    try
    {
        if (Looper.myLooper() == Looper.getMainLooper()){
            Log.d("Thread", "UI Thread");
        }
        binding.queryDataAsync(request);
    }
    catch (Exception e)
    {
        authenticationResponse = WebServiceResponseMessage.EXCEPTION + e.getMessage();
    }
}

ModelADServiceSoapBinding executeAsyn c метод (вызывается, когда мы запускаем binding.queryDataAsyn c ())

protected <T> android.os.AsyncTask<Void, Void, OperationResult<T>> executeAsync(final Functions.IFunc<T> func,
        final String methodName)
{
    if (Looper.myLooper() == Looper.getMainLooper()){
        // This is equal
    }
    return new android.os.AsyncTask<Void, Void, OperationResult<T>>() {
        @Override
        protected void onPreExecute()
        {
            callback.Starting();
            // This is being hit
        };

        @Override
        protected OperationResult<T> doInBackground(Void... params)
        {

            OperationResult<T> result = new OperationResult<T>();
            try
            {
                result.MethodName = methodName;
                result.Result = func.Func();
                WindowTabData wtd = (WindowTabData)result.Result;
                ADLoginResponse loginResponse = wtd.ADLoginResponse;
                // This works without exceptions
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
                result.Exception = ex;
            }
            return result; // This gets hit
        }

        @Override
        protected void onPostExecute(OperationResult<T> result)
        {
            Log.d("CallBack", "Callback"); // **THIS IS NEVER CALLED**
            callback.Completed(result);
        }
    }.execute();
}

На данный момент, я, вероятно, исчерпал свой мозг. MVP будет быстро заброшен, если мне придется потратить на это еще один день, поэтому, если какой-нибудь герой сможет пролить свет на это, я был бы очень признателен.

...