AsyncTask не возвращает значение во времени

Иногда, когда в процессе dev есть обе рабочие станции WIN и системы LINUX (хостинг), а в коде вы не видите никакого вывода перед соответствующей строкой, это может быть форматирование файла и отсутствие Unix LF (linefeed) заканчивается.

Что мы обычно делаем, чтобы быстро исправить это, переименуйте файл, а в системе LINUX создайте новый файл вместо переименованного, а затем скопируйте его в него. Во многих случаях это решает проблему, так как некоторые из файлов, которые были созданы в WIN, когда-то перемещенные на хостинг, вызывают эту проблему.

Это исправление - это легкое исправление для сайтов, которыми мы управляем по FTP, и иногда может спасти наш новый членов команды некоторое время.

0
задан Shahnawaz Ansari 13 July 2018 в 07:37
поделиться

3 ответа

Вы должны перенести свой код, как предложено в других ответах на метод onPostExecute(), иначе вы не можете знать, когда получить результат, потому что он работает в отдельном потоке. Итак, вы можете сделать что-то вроде приведенного ниже примера:

public class DatabaseCheckTask extends AsyncTask<String,Integer,Integer>{
int isRegistered;
/* use WeakReference to avoid leaks */
private WeakReference<ProgressBar> progressBarRef;
private WeakReference<Activity> activityRef;

public DatabaseCheckTask(ProgressBar progressBar, Activity activity){

    this.progressBarRef = new WeakReference<>(progressBar);
    this.activityRef = new WeakReference<>(activity);
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    // get the progressBar
    ProgressBar progressBar = progressBarRef.get();
    // show the progressBar
    progressBar.setVisibility(View.VISIBLE);
}

@Override
protected void onPostExecute(Integer userRegistered) {
    super.onPostExecute(userRegistered);
    Activity mActivity = activityRef.get();
    switch (userRegistered){
    case 1:
        Log.d("signup","SIGNUP");
        SignUpTask signUpTask = new SignUpTask();
       /* Assuming you pass these variables to you asynctask.execute() and stock them 
       globally */
        signUpTask.execute(first_name,last_name,roll_no,phone_no,serial);
       /* you have a reference to the activity, so you can get sharedPrefereces doing 
       mActivity.getSharedPref.... */
       sharedPreferences.edit().putBoolean(Constants.FIRST_RUN,false).apply();
       break;
   case 2:
       Log.d("signup","NOSIGNUP");
       Toast.makeText(mActivity,"Student with this Roll number is 
       registered already..",Toast.LENGTH_LONG).show();
       break;
   case 3:
       Log.d("signup","DATABASE_ERROR");
       Toast.makeText(mActivity,"Error connecting to database! Please try again 
       after some time.",Toast.LENGTH_LONG).show();
       break;
   default:
       Log.d("signup","DEFAULT_CASE");
       Toast.makeText(mActivity,"Slow",Toast.LENGTH_LONG).show();
   }
       ProgressBar progressBar = progressBarRef.get();
       progressBar.setVisibility(View.INVISIBLE);

}

Чтобы избежать утечек, вы должны использовать WeakReference , а затем вы можете контролировать видимость ProgressBar (progressBar ref), показывая Тосты и получение SharedPreferences (активность ref).

Я заменил ProgressDialog на ProgressBar, потому что он устарел в API level 26

И наконец, вы можете использовать свой AsyncTask, как показано ниже:

DatabaseCheckTask task = new DatabaseCheckTask(progressBar, MainActivity.this);
task.execute(/* Your variables);

UPDATE:

Но проблема здесь, в вашей AsyncTask doInBackground(), вы просто добавляете слушателя, который работает в отдельном потоке тоже есть причина, почему, даже если вы добавляете свой код в onPostExecute (), он не работает (событие еще не запущено).

Решение состоит в том, чтобы переместить каждый код оператора «case» в соответствующее место размещения в вашем слушателе. (Вам не нужен AsyncTask). Просто создайте функцию, которая принимает roll_no как параметр и которая добавляет слушателя

0
ответ дан E.Abdel 17 August 2018 в 13:26
поделиться
  • 1
    Это, все та же проблема. Однако для обнаружения проблемы я добавил дополнительный случай к моему предыдущему коду и обнаружил, что метод проверки существования узла не возвращает значение в настоящее время. Проверьте код здесь - AsyncTask и debug . Взгляни, пожалуйста. Pastebin, потому что я не хочу редактировать исходный код. – Shahnawaz Ansari 13 July 2018 в 10:10
  • 2
    @ShahnawazAnsari, пожалуйста, проверьте мое обновление – E.Abdel 13 July 2018 в 10:33
  • 3
    Благодаря! Я не знал, что слушатель работает в отдельном потоке. Это объясняет проблему. – Shahnawaz Ansari 13 July 2018 в 15:57

Переместите блок переключателей в onPostExecute() внутри вашего DatabaseCheckTask

@Override 
protected void onPostExecute(Integer integer)
 { 
super.onPostExecute(integer);
 //move your switch code here 
}
1
ответ дан Hemant Parmar 17 August 2018 в 13:26
поделиться

AsyncTask выполняет свой код в отдельном потоке, который отличается от основного потока, и поэтому основной поток будет продолжать выполнять свой код, в то время как AsyncTask будет запускать свой код в отдельном потоке. Вам придется подождать, пока метод doInBackground() AysncTask завершит свое выполнение, а затем продолжит работу с SignUp или другим (в зависимости от случая). Таким образом, вам придется перевести свой код на onPostExecute(), который запускается в основном потоке. Чтобы узнать больше об AsyncTask и его методах, см. this . Примечание. Вы не можете приостановить основной поток до тех пор, пока AsyncTask не завершит выполнение, но вы можете подождать, пока AsyncTask будет генерировать его результат, см. this .

1
ответ дан Sudhanshu Vohra 17 August 2018 в 13:26
поделиться
Другие вопросы по тегам:

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