Если AsyncTask не является внутренним классом … – некоторые вопросы

1) Я не недооцениваю и почему образцы Android почти используют AsyncTasks как частные внутренние классы. Я знаю, что это удобно, чтобы сделать его внутренним классом, но это делает наш классный файл более длинным и трудным для чтения . Прикладные образцы для стеллажей для образцов полок имеют даже 845 линий. Разве вы не думаете, что это плохой дизайн или плохая конструкция?

2) Если я создаю внешний класс ScanStorageTask, что мне нужно передать ему? Целая активность или только используемые виджеты?

Пример. Если я должен использовать WebView, кнопку и ProgressBar в ScanStorageTask. Я использую это:

ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it. 

или это:

 ScanStorageTask task = new ScanStorageTask(webView, button, progressBar); 

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

Почему бы не сделать это извне и использовать шаблон «слушателя», который использует пользовательский интерфейс? Сделайте свой ScanStorageTask своим собственным классом, создайте интерфейс OnCompleteListener с помощью метода onComplete и передайте его в экземпляр ScanStorageTask (выведите метод setOnCompleteListener или что-то в этом роде). Тогда onPostExecute может просто сделать это:

 if(onCompleteListener != null) onCompleteListener.onComplete(data); 

Таким образом, вы определяете свои обновления пользовательского интерфейса внутри своей деятельности на основе данных . Это лучшее разделение проблем и будет держать ваши строки кода в классе вниз, так как это похоже на то, что вы бы предпочли. Если вы еще этого не сделали, создайте класс, который представляет данные, которые вам нужно передать и выйдите, и вот что вы передаете заданию в качестве параметра для метода execute и что onPostExecute переходит к onComplete.

Внутренние классы позволяют вам манипулировать интерфейсом внешней Activity внутри onPreExecute() , onPostExecute() и onProgressUpdate() без передачи всей структуры пользовательского интерфейса в AsyncTask. Вы просто можете использовать для этого функции activites.

Это полезно, поскольку манипулирование пользовательским интерфейсом не является основной целью AsyncTask. Работает без фонового рисунка. И для этого то, что вы, как правило, должны пройти, – это некоторые аргументы для выполнения этой задачи (например, предоставление URL-адреса для загрузки файла).

Когда вы объявляете внешний внешний вид AsyncTask, вы в основном не можете получить доступ к своим ресурсам пользовательского интерфейса внутри onPreExecute() (никакие аргументы не передаются вообще) и очень сложно в пределах двух других функций пользовательского интерфейса.

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

AsyncTask обеспечивает правильное и простое использование потока пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.

(Из документации по классу )

У меня была та же проблема в приложении. Я хотел установить связь с ПК с помощью Socket и я хотел, чтобы мой код можно было повторно использовать из нескольких действий / фрагментов.

Во-первых, я старался не использовать внутренний класс, но очень удобно, когда вам нужно обновить интерфейс, поэтому я нашел альтернативное решение:
Я создал внешний класс AsyncTask отвечает за общение с ПК, и я создал внутренние классы в каждой из моих активностей / фрагментов с переопределением метода onPostExecute() . Таким образом я могу повторно использовать мой код И обновлять интерфейс.

Если вы просто хотите получить результат задачи, и если отзывчивость не является существенной для вашего приложения, вы можете использовать метод get () класса AsyncTask .

  1. Лично я считаю, что если вы используете класс только в один момент, то наиболее читаемым также можно определить его там – следовательно, внутренний класс anon.

  2. Это не имеет значения. С точки зрения дизайна я бы только передал данные, которые действительно нужны. Однако вам нужно знать об одной возможной ловушке – когда объект активности деактивируется (скрытый или измененный ориентация), а фоновый поток все еще работает и пытается показать некоторые изменения, тогда вы можете получить различные ошибки или вообще ничего не показывать.