Использование AsyncTask

Извиняюсь, если это простой вопрос, но я новичок в этом и все еще учусь.

У меня есть приложение, и когда мои пользователи нажимают кнопку для входа после ввода своих данных, происходит сбой с android.os.NetworkOnMainThreadException. Я обнаружил, что это происходит потому, что я выполняю сетевую операцию в главном потоке, и для ее решения мне нужно использовать AsyncTask, я застрял, однако, с синтаксисом.

Вот мой код после нажатия кнопки, вызывает функцию для подключения, а затем анализирует json в sqlite db.

// Login button Click Event
    btnLogin.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            String email = inputEmail.getText().toString();
            String password = inputPassword.getText().toString();
            UserFunctions userFunction = new UserFunctions();
            JSONObject json = userFunction.loginUser(email, password);

            // check for login response
            try {
                if (json.getString(KEY_SUCCESS) != null) {
                    loginErrorMsg.setText("");
                    String res = json.getString(KEY_SUCCESS); 
                    if(Integer.parseInt(res) == 1){
                        // user successfully logged in
                        // Store user details in SQLite Database
                        DatabaseHandler db = new DatabaseHandler(getApplicationContext());
                        JSONObject json_user = json.getJSONObject("user");

                        // Clear all previous data in database
                        userFunction.logoutUser(getApplicationContext());
                        db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));                        

                        // Launch Dashboard Screen
                        Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);

                        // Close all views before launching Dashboard
                        dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        startActivity(dashboard);

                        // Close Login Screen
                        finish();
                    }else{
                        // Error in login
                        loginErrorMsg.setText("Incorrect username/password");
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    });

Как я могу изменить это на правильный класс? Я не передаю URL и т. Д. Я думаю, что это должно быть примерно так, но я действительно изо всех сил пытаюсь получить правильный синтаксис.

Большое спасибо!!!

class login extends AsyncTask<Void, Void, Void> {

    private Exception exception;

    protected ??? doInBackground(???) {
        try {

1 ответ

Решение

Было бы что-то вроде этого

   public class TalkToServer extends AsyncTask<Void, Void, Void> {

   @Override
   protected void onPreExecute() {
        /*
         *    do things before doInBackground() code runs
         *    such as preparing and showing a Dialog or ProgressBar
        */
   }

   @Override
   protected void onProgressUpdate(Void... values) {
        /*
         *    updating data
         *    such a Dialog or ProgressBar
        */

   }

   @Override
   protected Void doInBackground(Void... params) {
      //do your work here
      return null;
   }

   @Override
   protected void onPostExecute(Void result) {
        /*
         *    do something with data here
         *    display it or send to mainactivity
         *    close any dialogs/ProgressBars/etc...
        */
   }
}

Тогда вы можете выполнить это с

TalkToServer myTask = new MyTask(); // can add params for a constructor if needed
myTask.execute(); // here is where you would pass data to doInBackground()

Вам может не понадобиться onProgressUpdate() или же onPreExecute() если вы не используете их, чтобы показать Dialog, прогресс или другие задачи до или во время doInBackground(),

onPreExecute() может использоваться для инициализации и отображения ProgressDialog, Тогда это может быть отклонено в onPostExecute()

После завершения задачи

onPostExecute() будет называться. Если класс является внутренним классом вашего Activity тогда вы можете обновить UI элементы там или вызвать функцию для запуска кода после завершения задачи. Если это отдельный файл, чем Activity тогда вы можете использовать interface и создать callBack к Activity и запустите код там после завершения задачи.

Этот ответ говорит об использовании интерфейса для обратного вызова, если вам нужно

Убедитесь, что любой UI обновление выполняется любым способом, кроме doInBackground() или отправлены обратно в Activity в любой функции, кроме doInBackground(), Тяжелые, такие как сетевые операции должны быть сделаны в doInBackground(),

Кроме того, не забудьте полностью прочитать документы AsyncTask. Особенно правила потоков

Другие вопросы по тегам