Google Android - это несложно

Добро пожаловать на форум сайта startandroid.ru
Текущее время: 23 окт 2018, 23:20

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 114 ]  На страницу Пред.  1, 2, 3, 4, 5, 6
Автор Сообщение
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 16 янв 2015, 13:00 
Аватар пользователя

Зарегистрирован: 07 дек 2013, 22:07
Сообщений: 182
Благодарил (а): 7 раз.
Поблагодарили: 0 раз.
Mikhail_dev писал(а):
А собственно как нотификейшн связан с UI, кроме того, что он может открыть какую-то активность?


Это я привел довод KamiSempai - доступ к UI из сервиса нужен в том числе для доступа к нотификейшн.

Цитата:
UI поток = обычный поток. Его просто назвали UI потоком. Он ничем не отличается от других. Я так понимаю там жестко прописали мол если с рутового потока запускать сетевую задачу, то писать что "NetworkOnMainThreadException". Так что да, сервисы имеют разные потоки. А GUI потоков не существует.


А Exception возникает только в случае обращения к сети, или вообще при любой задаче, которая надолго держит UI?

Например, TimeUnit.SECONDS.sleep(1000) в UI у меня исключение не вызывает.

Цитата:
Да. Используйте IntentService, он запускает задачи в отдельном потоке (не процессе).


Спасибо за наводку! Сейчас читаю, похоже то что нужно.

Цитата:
Это не совсем прозрачная тема. Первое - это то, что памяти выделяется больше (столько же, сколько и для нового приложения).


А на жизненный цикл сервиса его выделение в отдельный процесс как-то влияет?

_________________
Arbeit macht Fry


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 14 мар 2015, 21:01 
Аватар пользователя

Зарегистрирован: 29 май 2012, 09:57
Сообщений: 55
Благодарил (а): 6 раз.
Поблагодарили: 3 раз.
Привет, как поддерживать поворот экрана, когда asyncTask был вызван из фрагмента.
Таск тянет данные из инета и передает их во фрагмент.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 01 авг 2015, 10:45 

Зарегистрирован: 11 июл 2015, 17:54
Сообщений: 7
Благодарил (а): 1 раз.
Поблагодарили: 1 раз.
Подскажите, зачем нужен unlink? Мы же все равно поменяем ссылку переменной activity(класс MyTask) в новом активити, и она уже не будет ссылаться на старый активити.
И ещё интересный момент: после уничтожения активити (OnDestroy) таск может ещё работать с активити и при этом не выпадает никаких исключений. Почему?
И по-моему, неправильно передавать старый таск в новое активити. Лучше просто сохранить состояние в тот же preference и в OnCreate нового активити считывать.
Тут ещё после закрытия приложения этот таск будет продолжать работать, поэтому MyTask нужно объявить булеву переменную для управления отменой задачи и еще несколько строчек кода в методах onRetainNonConfigurationInstance, OnDestroy, link.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 18 сен 2015, 21:16 
Аватар пользователя

Зарегистрирован: 09 сен 2015, 13:53
Сообщений: 19
Благодарил (а): 1 раз.
Поблагодарили: 5 раз.
Урок 91 последний в группе уроков про AsyncTask и я тут накидал небольшой пример с комментариями в коде в котором находятся все задачи которые мы прошли, может кому пригодится, или кто-то посмотрит как можно реализровать тот или иной функционал. В общем все то, что мы прошли, ничего нового:

1. AsyncTask выполняется в отдельном потоке и эмулирует "тяжелый процесс", объект MyTask сохраняется и передается в новый Актвити при уничтожении старого. То есть отдельный поток MyTask не теряется. Используется новый метод onRetainCustomNonConfigurationInstance() вместо устаревшого onRetainNonConfigurationInstance()
2. MyTask класс наследует AsyncTask и объявлен как вложенный статический, чтобы избежать внутренней ссылки на внешний класс (в отличии от внутреннего).
3. в MyTask есть методы link() & unlink() чтобы обнулять ссылку на объект Актвити перед уничтожением старого активити (в случае смены ориентации экрана) и подключать ее после создания нового активити.
3. класс MyTask выполняет onPreExecute() и onPostExecute(), а так же onProgressUpdate(), который постонно передает в UI обновление хода процесса.*
4. * - из-за того что doInBackground() бежит в отдельном потоке и постоянно обращается к UI с помощью метода publishProgress() то иногда при повороте экрана происходит ситуация когда unlink уже обнулил ссылку на активити, а link еще не присвоил ее и в этот момент publishProgress() обращается к activity который равен null и соответственно падает с NullPointerException. Для этого сделал небольшой "буфер" в который складываются данные пока activity не будет назначен.
5. Реализована кнопка Cancel с досрочной остановкой потока MyTask
6. Кнопка Start неактивна пока процесс работает.
7. Результат который постоянно передается в TextView не обнуляется при поворотах экрана и выглядит все красиво. Используется onSaveInstanceState() и onRestoreInstanceState()

в коде подробные комментарии. За указания на ошибки или предложения лучшего решения буду на самом деле очень благодарен

layout/main.xml
Код: [ Загрузить ] [ Скрыть ]
Using XML Syntax Highlighting
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.    xmlns:tools="http://schemas.android.com/tools"
  3.    android:layout_width="match_parent"
  4.    android:layout_height="match_parent"
  5.    android:padding="10dp"
  6.    tools:context=".MainActivity">
  7.     <Button
  8.        android:id="@+id/btnCancel"
  9.        android:layout_width="wrap_content"
  10.        android:layout_height="wrap_content"
  11.        android:text="@string/btnCancel" />
  12.     <Button
  13.        android:layout_toEndOf="@id/btnCancel"
  14.        android:id="@+id/btnStart"
  15.        android:layout_width="wrap_content"
  16.        android:layout_height="wrap_content"
  17.        android:text="@string/btnStart" />
  18.  
  19.     <ProgressBar
  20.        android:id="@+id/pb"
  21.        android:layout_width="wrap_content"
  22.        android:layout_height="wrap_content"
  23.        android:layout_toEndOf="@id/btnStart"
  24.        />
  25.  
  26.     <TextView
  27.        android:id="@+id/tvStatus"
  28.        android:layout_width="wrap_content"
  29.        android:layout_height="wrap_content"
  30.        android:layout_below="@id/btnStart"
  31.        android:text="Status: " />
  32.  
  33.     <TextView
  34.        android:id="@+id/tvResult"
  35.        android:layout_width="wrap_content"
  36.        android:layout_height="wrap_content"
  37.        android:layout_below="@id/tvStatus"
  38.        android:text="..."
  39.        android:textSize="25sp" />
  40.  
  41. </RelativeLayout>
  42.  



MainActivity.java:
Код: [ Загрузить ] [ Скрыть ]
Using Java(TM) 2 Platform Standard Edition 5.0 Syntax Highlighting
  1. package com.mypackage.sa091_asynctask_5_retainactivityandmytask;
  2.  
  3. import android.os.AsyncTask;
  4. import android.os.Bundle;
  5. import android.support.v7.app.AppCompatActivity;
  6. import android.util.Log;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.ProgressBar;
  10. import android.widget.TextView;
  11.  
  12. import java.util.concurrent.TimeUnit;
  13.  
  14. public class MainActivity extends AppCompatActivity {
  15.     private static String LOG_TAG = "myLogs";
  16.  
  17.     private TextView tvResult, tvStatus;
  18.     private Button btnStart, btnCancel;
  19.     private ProgressBar pb;
  20.  
  21.     private MyTask task;
  22.  
  23.     @Override
  24.     protected void onCreate(Bundle savedInstanceState) {
  25.         super.onCreate(savedInstanceState);
  26.         setContentView(R.layout.main);
  27.  
  28.         tvResult = (TextView) findViewById(R.id.tvResult);
  29.         tvStatus = (TextView) findViewById(R.id.tvStatus);
  30.         btnStart = (Button) findViewById(R.id.btnStart);
  31.         btnCancel = (Button) findViewById(R.id.btnCancel);
  32.  
  33.         pb = (ProgressBar) findViewById(R.id.pb);
  34.         pb.setVisibility(View.GONE);
  35.  
  36.         /*
  37.         Восстанавливаем сохраненный объект MyTask при создании нового Активити:
  38.          */
  39.         task = (MyTask) getLastCustomNonConfigurationInstance();
  40.         /*
  41.         Если Активити создается первый раз значит создадим MyTask конструктором:
  42.          */
  43.         if (task == null) {
  44.             task = new MyTask();
  45.         }
  46.         /* Присваиваем текущий объект Активити в поле объекта MyTask чтобы там был доступ к View элементам:
  47.         */
  48.         task.link(this);
  49.  
  50.         /*
  51.         Определяем с каким статусом отрисовывать кнопку Start, если AsyncTask поток выполняется
  52.         тогда она должна быть сразу неактивна при появлении.
  53.          */
  54.         btnStart.setEnabled(isStartable());
  55.  
  56.         btnStart.setOnClickListener(new View.OnClickListener() {
  57.             @Override
  58.             public void onClick(View v) {
  59.                 /* Делаем кнопку неактивной */
  60.                 btnStart.setEnabled(false);
  61.                 tvResult.setText("");
  62.  
  63.                 /* в кнопке Start еще раз создаем объект MyTask и добавляем в него текущий активити.
  64.                 Делается это чтобы повторно не стартовать уже отработавший объект MyTask (иначе Exception)
  65.                  */
  66.                 task = new MyTask();
  67.                 task.link(MainActivity.this);
  68.  
  69.                 Log.d(LOG_TAG, "---btnStart: MainActivity hash: " + MainActivity.this.hashCode() + " MyTask hash: " + task.hashCode());
  70.  
  71.                 task.execute("android developer 80 level ");
  72.             }
  73.         });
  74.  
  75.         btnCancel.setOnClickListener(new View.OnClickListener() {
  76.             @Override
  77.             public void onClick(View v) {
  78.                 if (task != null) task.cancel(false);
  79.             }
  80.         });
  81.     }
  82.  
  83.     /*
  84.     Готов к старту: если объект MyTask не равен null
  85.     и при этом он или Canceled или не RUNNING (значит PENDING или FINISHED)
  86.      */
  87.     private boolean isStartable() {
  88.         if (task != null && (task.isCancelled() || !task.getStatus().equals(AsyncTask.Status.RUNNING))) {
  89.             return true;
  90.         } else {
  91.             return false;
  92.         }
  93.     }
  94.  
  95.     /*
  96.     Сохраняем текст из tvResult и tvStatus для переноса в новое активити
  97.      */
  98.     @Override
  99.     protected void onSaveInstanceState(Bundle outState) {
  100.         super.onSaveInstanceState(outState);
  101.         outState.putString("tvResult", tvResult.getText().toString());
  102.         outState.putString("tvStatus", tvStatus.getText().toString());
  103.     }
  104.  
  105.     /*
  106.     Вставляем сохраненный текст из tvResult и tvStatus в новое активити из старого
  107.      */
  108.     @Override
  109.     protected void onRestoreInstanceState(Bundle savedInstanceState) {
  110.         super.onRestoreInstanceState(savedInstanceState);
  111.         tvResult.setText(savedInstanceState.getString("tvResult", ""));
  112.         tvStatus.setText(savedInstanceState.getString("tvStatus", ""));
  113.     }
  114.  
  115.     /*
  116.     Перед уничтожением Активити вызывается этот метод, который сохраняет объект MyTask с уже работающим потоком.
  117.     Чтобы он не держал старое Активити - убираем у него ссылку на объект Активити.
  118.      */
  119.     @Override
  120.     public Object onRetainCustomNonConfigurationInstance() {
  121.         if (task != null) {
  122.             task.unlink();
  123.         }
  124.         return task;
  125.     }
  126.  
  127.     /*
  128.     Вложенный класс MyTask сделали статическим чтобы он не содержал скрытую ссылку на внешний класс Активити
  129.      */
  130.     static class MyTask extends AsyncTask<String, Character, String> {
  131.  
  132.         MainActivity activity;
  133.         StringBuffer sb = new StringBuffer();
  134.  
  135.         public void link(MainActivity activity) {
  136.             this.activity = activity;
  137.         }
  138.  
  139.  
  140.         public void unlink() {
  141.             activity = null;
  142.         }
  143.  
  144.  
  145.         @Override
  146.         public void onPreExecute() {
  147.             activity.tvStatus.setText("Status: Begin");
  148.             activity.pb.setVisibility(View.VISIBLE);
  149.         }
  150.  
  151.         public String doInBackground(String[] strings) {
  152.             int i = 0;
  153.             for (char c : strings[0].toCharArray()) {
  154.                 try {
  155.                     i++;
  156.                     if (isCancelled()) return "";
  157.                     TimeUnit.MILLISECONDS.sleep(200);
  158.                     publishProgress(c);
  159.  
  160.                 } catch (InterruptedException e) {
  161.                     e.printStackTrace();
  162.                 }
  163.             }
  164.             return i + " chars successfully printed";
  165.         }
  166.  
  167.         /*
  168.         Если новый (AsynkTask) поток продолжает работать и в этот момент пересоздастся Активити, то в
  169.         какой-то короткий момент объект класса MyTask (поток AsynkTask) не будет иметь ссылку на Активити.
  170.         Это происходит в момент когда unlink уже отработал, но link еще не сработал (В Main потоке),
  171.         а в AsynkTask потоке произошло обращение к эелменту в активити (например вызовом publishProgress()
  172.         который вызывает onProgressUpdate()) - тогда сработает исключение NullPointerException.
  173.         Для этого в методе onProgressUpdate() делаем буфер куда будет складываться промежуточная
  174.         информация в случае activity == null.
  175.         Когда активити вновь будет присвоен - этот буффер обновит элементы в актвити и будет очищен.
  176.          */
  177.         @Override
  178.         public void onProgressUpdate(Character[] characters) {
  179.             if (activity == null) {
  180.                 sb.append(characters[0]);
  181.             } else {
  182.  
  183.                 if (sb.length() > 0) {
  184.                     activity.tvResult.append(sb.toString());
  185.                     sb.setLength(0);
  186.                 }
  187.                 activity.tvResult.append(characters[0].toString());
  188.  
  189.                 Log.d(LOG_TAG, "---doInBackground: " + characters[0] + "  MainActivity hash: " + activity.hashCode() +
  190.                         " MyTask hash: " + this.hashCode());
  191.             }
  192.  
  193.  
  194.         }
  195.  
  196.         /*
  197.         onPostExecute() выполняется когда doInBackground закончил работу.
  198.         Если к этому моменту активити так и не был назначен - вываливаем буфер здесь.
  199.          */
  200.         @Override
  201.         public void onPostExecute(String result) {
  202.             if (activity == null) return;
  203.  
  204.             activity.tvStatus.setText("Status: End. " + result);
  205.             activity.pb.setVisibility(View.GONE);
  206.             if (sb.length() > 0) {
  207.                 activity.tvResult.append(sb.toString());
  208.             }
  209.              /* Делаем кнопку активной */
  210.             activity.btnStart.setEnabled(true);
  211.         }
  212.  
  213.         /*
  214.         если был вызван метод cancel() тогда onCancelled() выполняется вместо onPostExecute()
  215.         поэтому здесь делаем то же что и в onPostExecute - вываливаем буфер во View элементы
  216.         и делаем кнопку Start вновь активной.
  217.         */
  218.         @Override
  219.         protected void onCancelled() {
  220.             super.onCancelled();
  221.             if (activity == null) return;
  222.  
  223.             activity.tvStatus.setText("Status: Canceled");
  224.             activity.pb.setVisibility(View.GONE);
  225.             if (sb.length() > 0) {
  226.                 activity.tvResult.append(sb.toString());
  227.             }
  228.  
  229.             /* Делаем кнопку активной */
  230.             activity.btnStart.setEnabled(true);
  231.         }
  232.     }
  233. }
  234.  
  235.  


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 18 сен 2015, 23:26 
Аватар пользователя

Зарегистрирован: 09 янв 2012, 14:45
Сообщений: 2386
Откуда: Самара
Благодарил (а): 102 раз.
Поблагодарили: 321 раз.
Стесняюсь спросить, но знаете ли вы про Loaders? И если да, то что вы сделали кардинально нового, в отличии от стандартных лодеров (к примеру AsyncTaskLoader, название которого как бы намекает...) ?

_________________
Изображение

А тот ли ты путь выбрал, разработчик?
Хочешь знать ошибки ответ? Загляни в logcat!


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 19 сен 2015, 02:32 
Аватар пользователя

Зарегистрирован: 23 ноя 2013, 16:08
Сообщений: 1107
Откуда: Ukraine
Благодарил (а): 31 раз.
Поблагодарили: 175 раз.
Mikhail_dev писал(а):
Стесняюсь спросить, но знаете ли вы про Loaders? И если да, то что вы сделали кардинально нового, в отличии от стандартных лодеров (к примеру AsyncTaskLoader, название которого как бы намекает...) ?

Поймал рофляночку с тигра.

_________________
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 19 сен 2015, 11:05 
Аватар пользователя

Зарегистрирован: 09 сен 2015, 13:53
Сообщений: 19
Благодарил (а): 1 раз.
Поблагодарили: 5 раз.
Mikhail_dev писал(а):
Стесняюсь спросить, но знаете ли вы про Loaders?

пока нет, я иду с первого урока. Loader будет на 135

Mikhail_dev писал(а):
И если да, то что вы сделали кардинально нового, в отличии от стандартных лодеров (к примеру AsyncTaskLoader, название которого как бы намекает...) ?

Kirill писал(а):
накидал небольшой пример с комментариями в коде в котором находятся все задачи которые мы прошли, может кому пригодится, или кто-то посмотрит как можно реализровать тот или иной функционал. В общем все то, что мы прошли, ничего нового:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 27 окт 2015, 12:16 

Зарегистрирован: 22 июл 2015, 13:45
Сообщений: 12
Благодарил (а): 3 раз.
Поблагодарили: 1 раз.
Есть Activity с ExpandableListView.
Хочу организовать загрузку данных в этот ExpandableListView из базы данных не в UI.
Изпользую AsyncTask, как в уроке.
Но есть проблема.
Кратко:
Имеется объект класса для загрузки данных:
Код: [ Загрузить ] [ Скрыть ]
  1. public class DataBaseHelper extends SQLitOpenHelper { 
  2. ... 
  3. public DataBaseHelper(Context context) 
  4.   super(context,...); 
  5. ... 

Далее в doInBackground
используются объекты:
Код: [ Загрузить ] [ Скрыть ]
  1.   DataBaseHelper dbh = new DataBaseHelper(activity); 
  2.   SQLiteDatabase db; 
  3.  
  4. ... 
  5.   db = dbh.getReadableDatabase(); 

Как только переворачиваю эмулятор - ес-но вываливается ошибка на вышеприведённой строчке.
Т.к. активность уничтожена, соот-но её контекст уже того.
Вопрос - как быть?
1. Сделать загрузку в сервисе - но чё-то кажется что ради загрузки данных в ExpanableListView это сильно жирно.
2. Смотреть в сторону AsyncTaskLoader (ещё не читал, но как понял из обсуждений, если передернуть экран - то этот лоадер может задачу убить и запустить заново).
Но тоже сомнения - если будут экран туда сюда дергать - оно так и не загрузится. Хотя, может, что-то в этом есть.
3. Какой-то иной вариант?
В идеале бы хотелось, чтобы AsyncTask загрузил все данные независимо от наличия/отсутствия активности, а потом, как активность будет доступна - получила бы сама данные методом get и всё (так и сделал в другой активности, где идёт загрузка текстового файла, но тут для базы данных нужен контекст, будь он неладен :) )


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 27 окт 2015, 14:20 

Зарегистрирован: 22 июл 2015, 13:45
Сообщений: 12
Благодарил (а): 3 раз.
Поблагодарили: 1 раз.
Вопрос отменяется!
Всё решилось вызовом getApplicationContext.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 30 дек 2015, 20:16 

Зарегистрирован: 30 дек 2015, 20:06
Сообщений: 1
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Цитата:
Напишу здесь свой вариант решения. В методе onProgressUpdate мы ставим проверку activity == null. Если activity - не null, то без проблем меняем textView. Если же activity - null, то текст, который мы хотели прописать в TextView, мы сохраняем в какую-нить свою переменную класса MyTask. А новое Activity, когда получает MyTask, достает данные из этой переменной и сама помещает их в TextView.

А что будет если мы проверили ссылку на activity она не равна null.
Затем мы начинаем что-то делать с визуальными объектами activity и вот тут пропадёт ссылка на сам activity.
Или в момент времени когда мы проверяли activity на null в нём ещё находилась ссылка, а потом мы поворачиваем экран ссылка пропадает, а мы начнём что-то менять и тут вылетит ошибка, что нет указателя или ссылки (не суть) на activity.
Вероятность возникновения этого всего конечно очень маленькая, но по моему она есть :(


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 09 янв 2016, 10:12 

Зарегистрирован: 09 янв 2016, 10:10
Сообщений: 4
Благодарил (а): 2 раз.
Поблагодарили: 0 раз.
Такой вопрос, а зачем вообще было всё это городить, если можно просто в манифесте прописать в активити configChanges="orientation|screenSize" и активность не будет убиваться при повороте экрана? Так ведь намного проще и эффективнее.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 20 фев 2016, 12:04 

Зарегистрирован: 20 фев 2016, 11:54
Сообщений: 2
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
AIRIZZIO писал(а):
Такой вопрос, а зачем вообще было всё это городить, если можно просто в манифесте прописать в активити configChanges="orientation|screenSize" и активность не будет убиваться при повороте экрана? Так ведь намного проще и эффективнее.


Вот здесь - http://stackoverflow.com/questions/7818717/why-not-use-always-androidconfigchanges-keyboardhiddenorientation не рекомендуют без особой на то необходимости использовать configChanges="orientation|screenSize", т.к. активность может уничтожаться не только при смене ориентации, но и, например, при смене языка и в ситуации когда заканчивается память в устройстве.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 26 июн 2016, 01:18 

Зарегистрирован: 07 июн 2016, 18:07
Сообщений: 6
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Mikhail_dev писал(а):
Стесняюсь спросить, но знаете ли вы про Loaders? И если да, то что вы сделали кардинально нового, в отличии от стандартных лодеров (к примеру AsyncTaskLoader, название которого как бы намекает...) ?


Как в этом AsyncTaskLoader сделать так, чтобы новый таск не запускался каждый раз при повороте экрана?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Урок 91. AsyncTask. Поворот экрана
СообщениеДобавлено: 18 апр 2018, 07:08 

Зарегистрирован: 18 апр 2018, 07:07
Сообщений: 1
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Скопировал все как в уроке, в итоге:

Error:(32, 19) error: onRetainNonConfigurationInstance() in MainActivity cannot override onRetainNonConfigurationInstance() in FragmentActivity
overridden method is final
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 114 ]  На страницу Пред.  1, 2, 3, 4, 5, 6

Часовой пояс: UTC + 3 часа


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB