Не получается выполнить AsyncTask

238
24 ноября 2017, 07:05

Есть одна Activity, в которой при клике на определенную кнопку выполняется AsyncTask, который в свою очередь делает запрос на API, чтобы получить токен для пользователя:

import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity  {
    private Button submit;
    private EditText loginLabel;
    private EditText passwordLabel;
    private TextView errorLabel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        loginLabel = (EditText) findViewById(R.id.login);
        passwordLabel = (EditText) findViewById(R.id.password);
        errorLabel = (TextView) findViewById(R.id.errorLabel);
        submit = (Button) findViewById(R.id.button);
        submit.setOnClickListener(
                new View.OnClickListener()
                {
                    @Override
                    public void onClick(View v)  {
                        String login = loginLabel.getText().toString();
                        String password = passwordLabel.getText().toString();
                        // AsyncTask Execute
                        Auth user = new Auth();
                        user.execute(login, password);
                        String token = user.getToken();
                        // При попытке вывести token через out.println - NullPointerException и остановка программы.
                        if (token != null && !token.trim().isEmpty()) {
                            Intent intent = new Intent(v.getContext(), CourierActivity.class);
                            intent.putExtra("token", token);
                            startActivity(intent);
                        } else {
                            errorLabel.setText("Неправильный логин или пароль");
                        }
                    }
                }
            }
        );
    }
    static class Auth extends AsyncTask<String, Void, String> {
        private String token;
        private String errorMessage;
        @Override
        protected String doInBackground(String... params) {
            String query = "Здесь URL";
            HttpURLConnection connection = null;
            try {
                connection = (HttpURLConnection) new URL(query).openConnection();
                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                String urlParameters = "username=" + params[0] + "&password=" + params[1];
                DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
                dataOutputStream.writeBytes(urlParameters);
                dataOutputStream.flush();
                dataOutputStream.close();
                StringBuilder sb = new StringBuilder();
                if (HttpURLConnection.HTTP_OK == connection.getResponseCode()) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
                    String line;
                    while ((line = in.readLine()) != null) {
                        sb.append(line);
                        sb.append("\n");
                    }
                    return this.token = ServiceConnect.parse(sb.toString());
                } else {
                    this.errorMessage = "fail: " + connection.getResponseCode() + ", " + connection.getResponseMessage();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return this.token = null;
        }
        public String getToken() {
            return this.token;
        }
        public String getErrorMessage() {
            return this.errorMessage;
        }
    }
}

Код выполняется без AsyncTask, если присутствует этот код:

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 

Но, как говорит гугл, лучше это не использовать вообще. И без этих двух строчек вылетает Exception - android.os.NetworkOnMainThreadException.

В чем может быть ошибка? Уже что только не перепробовал. Мне нужно просто получить токен из запроса в API.

Answer 1

AsyncTask выполняет операцию асинхронно, это значит что вы не можете сразу же запросить у него результат. Сетевой запрос может длиться 5 секунд, например, а вы сразу пытаетесь после запуска достать значение, которого ещё нет, поэтому и null:

Auth user = new Auth();
user.execute(login, password);
String token = user.getToken();

Вы пропустили метод onPostExecute, в котором как раз и происходит возврат к MainThread. Тут и нужно выполнять обработку токена:

@Override
protected void onPostExecute(String token) {
    // тут приходит то, что возвращает doInBackground
    if (token != null && !token.trim().isEmpty()) {
        Intent intent = new Intent(v.getContext(), CourierActivity.class);
        intent.putExtra("token", token);
        startActivity(intent);
    } else {
        errorLabel.setText("Неправильный логин или пароль");
    }
}

А в doOnBackground вам нужно просто возвращать полученный токен или null если не удалось его получить

READ ALSO
Spring data save

Spring data save

Сущности

241
Java. Считать строки из файла

Java. Считать строки из файла

ЗдравствуйтеПомогите, пожалуйста

271
Разбор условия if(?:) return;

Разбор условия if(?:) return;

Подскажите пожалуйста, как можно озвучить данное условие if()

175