Android — android проблема с Handler!


Содержание
Цукерберг рекомендует:  Sql server - Посоветуйте книги по базам данных SQL Server

Утечка памяти при использовании Handler

Добрый день, многоуважаемые форумчане .
Прошу помощи в решении проблемы.

Приведу несложный исходный код.

Приложение простое и работает циклично. При его запуске создаётся и запускается таймер на 4 секунды, каждую секунду он уменьшается на секунду, отображая изменения в TextView. По завершении таймера вызывается метод method(), который после 5-секундной задержки запускает некоторые действия в отдельном потоке, а именно: отменяет старый таймер, создаёт новый и запускает его. Цикл повторяется по новой.

Если нажать на кнопку Back во время обратного отсчёта таймера, то таймер отменится и активити остановится. Вроде бы всё нормально.
НО если нажать на кнопку Back во время 5-секундной задержки (handler.postDelayed(. 5000); ), то после остановки активити поток продолжит свою работу и бесконечный цикл продолжится. Это можно услышать по звуку. Т.е., как я понимаю, это утечка.

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

10.10.2014, 14:48

Утечка памяти
Разработал программу, получилась достаточно большая, использует сторонние библиотеки, работает без.

Утечка памяти
Работаю в Android Studio Подскажите как определить утекает ли память при работе с программой или.

Утечка памяти в Spiner
Здравствуйте. Создал новый проект в Layout добавил выпадающий список в ресурсы добавил массив.

FragmentActivity -> DialogFragment (утечка памяти)
Всем привет! Обнаружил у себя такой баг: при повороте экрана — каждый раз увеличивается кол-во.

Javanese Online

Android — это плохой DI-контейнер

Очевидно, у большинства объектов есть зависимости, которые должны быть переданы через конструктор. Исключениями из правила являются синглтоны: либо у них нет зависимостей, либо они не должны быть синглтонами.

Наиболее приемлемым костылём может показаться использование Application , но он один на всех, поэтому Google рекомендует использовать статические синглтоны; нужно знать, что во время бэкапа Application будет предательски подменён, а после рестарта процесса все классы загрузятся заново и данные, хранившиеся в синглтонах, пропадут.

Такой подход становится феерической помехой повторному использованию кода: при добавлении новой функциональности она не делегируется объектам, которые передаются в конструктор, а реализуется прямо внутри фрагмента (активити, презентера, вьюмодели) в if-else/switch-case. Впоследствии такой класс становится типичным customizable object, подчиняющимся десяткам условий — а такой код крайне сложно поддерживать.

Ложку дёгтя добавляет жизненный цикл. Знание того, что Activity/Fragment — обычный Java-объект, оказывается немного неверно: после пересоздания ту же задачу выполняет уже другой объект, которому достаётся Bundle с сохранённым состоянием предшественника. Люди, не знающие Java, часто неверно интерпретируют пересоздание как «GC вычистил мне все ссылки!»

Иерархии типов

Нужно постоянно наследовать классы. Если какая-нибудь библиотека, например, хочет предоставить свои подтипы фрагментов, приходится учитывать, что есть нативные фрагменты ( android.app.Fragment ) и их бэкпорт ( android.support.v4.app.Fragment ), а также несколько особых случаев: DialogFragment , BottomSheetDialogFragment и т. п..

У бэкпортированных и нативных фрагментов одинаковый интерфейс (множество публичных методов), но они не реализуют один interface , следовательно, для поддержки обеих иерархий классов нужно создавать два экземпляра одного кода, которые различаются только импортами.

Чтобы поселить фактический сервис (просто объект, представляющий определённую функциональность) в Bound Service и передать его в Activity , нужно унаследовать как минимум Service и Binder (а также реализовать ServiceConnection ). Пример заворачивания объекта в сервис

Принеси с собой свои best practices

Как работать с асинхронностью?
AsyncTask
  • Невероятно странный интерфейс: метод execute() принимает дженерик, но задачу можно исполнить лишь один раз, поэтому проще передать параметр в конструктор; второй дженерик определяет тип промежуточных данных — он обычно не используется, поэтому имеет смысл завести для редкого случая отдельный класс — скажем, ProgressAsyncTask ; execute() и onPostExecute() принимают vararg, но в большинстве случаев передаётся ровно один объект; нельзя создавать и запускать AsyncTask из фона — onPreExecute() вызывается прямо из execute() , а в старых версиях статический инициализатор вызывает new Handler(без аргументов) , тем самым привязываясь к текущему Looper (если он есть); ничего не знает о жизненном цикле.
  • Loader полны багов, API монструозен. Считаются устаревшими начиная с Android Pie.
  • ThreadPoolExecutor — неплохой, хоть и старомодный, инструмент из Java, который, естественно, ничего не знает о жизненном цикле.
  • Корутины или монструозную RxJava несложно адаптировать для работы с Android (в частности, прерывать текущие задачи onDestroyView или onDestroy ), но их нужно приносить с собой, т. к. фреймворк их не содержит.
Работа с JSON

Я бы не стал использовать этот формат добровольно, но к этому принуждают многие публичные API.

  • org.json (AST), который есть в Android, хорош лишь в качестве академической реализации.
  • android.util.JsonReader (streaming) — копия com.google.gson.stream.JsonReader , немного оптимизированная для Android. Вообще, стриминг — достаточно низкоуровневый принцип, поверх которого обычно пишут более человечную реализацию. Но при этом JsonReader недостаточно низкоуровневый: он читает символы из Reader и возвращает строки в виде String , то есть доступа к нижележащему InputStream/byte[] он не имеет, что мешает выполнять некоторые оптимизации. Присутствует попытка убирать дубликаты строк с помощью libcore.internal.StringPool , но этот пул не умеет разрешать коллизии, поэтому после считывания нескольких сотен строк в пуле оседает от силы 30.
  • Практические реализации — Gson, Jackson, Moshi, Klaxon — нужно приносить с собой.

HttpURLConnection — это вообще издевательство. Конечно же, большинство использует OkHttp/Retrofit, пока Google пытается делать припарки библиотеке Volley.

Всё осложняется полнейшим отсутствием пакетного менеджера. В некоторых дистрибутивах Linux есть apt-get , apt или aptitude , на Mac OS можно установить brew . В Java-мире есть системы сборки Gradle, Maven и множество других. Все вышеперечисленные умеют скачивать пакеты, их зависимости, зависимости их зависимостей и т. д.. В Android нет ничего подобного — Gradle скачивает всё на многострадальный компьютер разработчика, ProGuard давится десятками библиотек, dx конвертирует их в Android-совместимый байт-код, программист загружает в маркет, пользователь — из маркета, рантайм верифицирует, загружает, компилирует все эти классы, собирает о них статистическую информацию для наиболее оптимального выполнения (profile-driven compilation). Всё это происходит снова и снова, даже если множество приложений используют одни и те же зависимости одинаковых версий, в том числе для таких крупных библиотек как AppCompat/Support, Google Mobile Services, ExoPlayer, Realm, FFMpeg. Последние две содержат нативный (машинный) код, что заставляет разработчиков собирать по несколько APK для разных архитектур (APK splits).

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

Context

Контекст — это god object. View , например, нужен не контекст, а тема и ресурсы. registerReceiver мог бы быть методом не Context , а Application (для локального броадкаста) и, допустим, AndroidSystem (выдуманный класс) для броадкаста по всей системе.

Особенно доставляет, что контексты бывают разные — приложения, сервиса, активити — и с ними нужно обходиться по-разному.

non-configuration instance

Retain-фрагменты переживают смену конфигурации. Слышали что-нибудь о retain-фрагментах без View ? Это костыль, который позволяет хранить объекты в таком фрагменте. В Activity есть похожий механизм — non-configuration instance (custom non-configuration instance у AppCompatActivity ). Отсюда вопрос: почему нельзя сделать Activity живучей, как retain-фрагмент, и почему у фрагмента, наоборот, нет non-configuration instance?

Ресурсы

У Android собственный механизм для доступа к ресурсам. Стандартные для Java ресурсы из classpath работают, но медленно и расточительно. Та же проблема затрагивает механизм ServiceLoader , т. к. META-INF/services — тоже ресурсы classpath.

Цукерберг рекомендует:  Отзывы о курсах .ru (ГикБрейнс) – обучение, стажировка, трудоустройство


XML — основной и официальный способ описания ресурсов — от вёрстки, меню, переводов и графики до конфигураций, примитивов и строк. Он хорошо подходит для случая, когда ОС/лончеру/шторке нужно достать ресурсы, не пробуждая приложение, но мешает всяческим попыткам написать лаконично, гибко и без дублирования. Присутствует (неудавшаяся) попытка исправить XML статической типизацией.

Каждый ресурс формально находится в определённом пакете (package) — изолированном пространстве имён. На практике таковых всего два — android и пакет текущего приложения; Android Gradle Plugin сливает ресурсы изо всех AAR-библиотек в пакет приложения, провоцируя потенциальные конфликты имён, а также страшные костыли с перегенерацией R.java .

AttributeSet — это интерфейс, но реализовывать его бесполезно: obtainStyledAttributes кастит его к XmlBlock.Parser — а это package-private класс. По сути, AttributeSet играет роль маркер-интерфейса, что есть антипаттерн.

Сама абстракция Drawable кажется мне очень удачной, а разнообразие коробочных реализаций радует глаз. Но атрибуты темы не работают на четвёрках, названия XML-тегов ( selector , shape ) отличаются от имён классов ( StateListDrawable , GradientDrawable ), возможность использовать в XML свои классы доступна аж с SDK 24, а Drawable paddings влияют на View paddings по-разному, в зависимости от версии Android.

В векторных картинках можно задавать путям цвета из темы (например, ?colorPrimary ). Но темы нельзя создавать из кода!

Нет никакой гарантии, что указанный ресурс вообще существует. Он может иметь значение только для определённых квалификаторов или не иметь его вовсе ( ).

shrinkResources удаляет неиспользуемые ресурсы, но как-то несерьёзно; оставшиеся ресурсы не переименовываются.

Remote views нельзя создать из кода, только XML. Что вносит множество ограничений.

LayoutParams можно создать только из одного XML-тэга. с layout_gravity , в котором находится с layout_margin , который содержит вью с layout_width и layout_height — нельзя, получайте непереиспользуемый код.

В XML-вёрстку нельзя передавать параметры, будь это хоть LayoutInflater#inflate , хоть или (а вот в любом шаблонизаторе такая возможность есть).

В XML-вёрстке нельзя поставить точку останова (breakpoint), что делает отладку ошибок вроде Binary XML file line #0: Error inflating class . чрезвычайно увлекательной. LayoutInflater работает рекурсивно, поэтому многие стектрейсы не вмещаются и обрезаются: 86 more.

findViewById — нечто абсолютно противоположное лаконичности и типобезопасности. Количество различных костылей, с этим связанных, превышает все мыслимые пределы.

Идеологически TypedArray — это массив TypedValue . Но функциональность у них разная: TypedArray предоставляет человеческий интерфейс из методов getText, getBoolean, getInt, getFloat, getColor, . , а TypedValue ничего из этого не умеет. Зато у TypedValue есть поле changingConfigurations , а вот TypedArray#getChangingConfigurations возвращает одно общее значение для всех элементов (за O(n)) и доступно только для 21+. В итоге приходится использовать TypedArray даже для единственного атрибута и прибегать к помощи TypedValue , даже когда имеется «человеческий» TypedArray .

changingConfigurations у классов ColorStateList, Theme, TypedArray, Drawable, TypedValue расскажут, при смене каких конфигураций ресурс инвалидируется. Казалось бы, чтобы обновлять ресурсы вовремя, нужно придержать айдишники всех ресурсов, которые могут инвалидироваться в течение жизни данного компонента (т. е. (component.configChanges & resource.configChanges) != 0 ) и переопределить onConfigurationChanged данного Activity или View , где и можно перезагрузить протухшие ресурсы. Но метод Activity#getChangingConfigurations предназначен для другого и возвращает осмысленное значение, только когда активити уничтожается, а у вью вообще нет подобного метода. Чтобы узнать, какие конфигурации обрабатывает текущая активити, нужно спросить ActivityInfo у PackageManager . Хотя нужный объект ActivityInfo уже есть у Activity . В приватном поле.

По умолчанию все ресурсы библиотеки считаются публичными. Как только появляются ресурсы, явно отмеченные, как публичные, все остальные становятся приватными. Android Lint отмечает использование «приватных» ресурсов как warning. Не хватает возможностей:

  • писать модификаторы доступа «на месте», а не в отдельном файле;
  • генерировать настоящую ошибку компиляции при использовании чужих приватных ресурсов;
  • кроме private in module иметь private in file, например, для идентификаторов, которые используются для позиционирования в RelativeLayout ;
  • писать документацию к ресурсам, по аналогии с javadoc и KDoc.

В итоге неплохо подходят для переводов, а растровые картинки нормально чувствуют себя в drawable-*dpi. Всё остальное настолько убого, негибко и многословно, что напрашивается на перенос в код.

Parcel

Писать собственную сериализацию — это всегда весело и задорно. Parcel очень напоминает DataInput и DataOutput из JDK, а Parcelable — это подобие Externalizable , но реализациями этих интерфейсов они не являются, что заставляет писать платформозависимый код. Parcel слегка походит на бинарные протоколы сериализации вроде Protobuf, но, опять же, им не является. Надо было затаскивать Protobuf во фреймворк: тогда сериализуемые этим путём объекты удобно было бы ещё и передавать по сети.

Parcelable.Creator нужно держать в статическом поле с именем CREATOR , чтобы фреймворк мог найти его рефлекшеном. При этом, не найдя CREATOR , фреймворк пойдёт искать его у суперклассов, откладывая возникновение ошибок десериализации на потом.

Асинхронные события и фрагменты

У фрагментов может случиться state loss. Очевидно, выполнение транзакций с фрагментами после сохранения состояния — это ошибка. Но фреймворк никак не поможет её найти — в асинхронных стектрейсах вообще не будет вашего кода.

Даже если транзакция выполняется в ответ на действие пользователя (например, непосредственно в OnClickListener ), Activity вполне может быть на паузе в этот момент. Банальное нажатие кнопки «назад» может привести к падению, приложению при этом вообще не обязательно использовать фрагменты.

Если пользователь сделает два быстрых клика, они оба вполне могут быть обработаны, даже если предполагается, что клик должен увести пользователя с текущего экрана. ButterKnife содержит костыль, который избавляет от множественных кликов.

Обратная совместимость

APK, собранные с использованием gradle plugin 3 и build-tools 26, ломают лончер и файловый менеджер Cyanogenmod.

В AppCompat 26 сломали target у фрагментов в тех случаях, которые не описаны (и никогда не были описаны) в документации как недопустимые.

В javadoc не проставлены @since . (На сайте они откуда-то всё же берутся.)

Слабые контракты

Intent может содержать Action (строка), Uri, Extras (Bundle, т. е. Map ). Для популярных extras есть заранее заготовленные ключи, например, Intent.EXTRA_EMAIL . Но нет типов. Так, можно попытаться открыть почтовый клиент, передав в качестве темы письма картинку, или открыть браузер, не передавая адреса веб-страницы. Чтение интента в видимой всей системе активити — поле непаханное для крэшей. Некоторые популярные приложения валились у меня на глазах при попытке поделиться картинкой. И дело не только в кривизне рук разработчиков, но и в изначальной проблемности такого механизма.

Кроме как в Extras, Bundle используется ещё и в аргументах фрагмента ( Fragment.setArguments ). Как всегда, нет гарантий, что по нужному ключу передан объект нужного типа.

Положим, у вас есть фрагмент, который принимает какой-то объект (выдумаем, например, ParcelUser ) через аргументы. И вы осознаёте, что не нужно передавать объект целиком, достаточно передать идентификатор пользователя ( ParcelUuid ). Счастливого рефакторинга!

Профилирование

Взамен Android Monitor сделали полурабочий Android Profiler. Да, я посвятил открыванию хип-дампов целый тред.

Взамен Android Device Monitor не сделали ничего. Благо, его не удалили по-настоящему, а просто убрали из меню в IDE.

Единственный профайлер, способный предоставить полезную информацию, — это стороннее решение. Method tracing бесполезен, т. к. выбрасывает скомпилированный (и даже интринсифицированный!) код и использует интерпретатор. Systrace помогает найти медленные места, но очень приблизительно, т. к. фреймворковые методы инструментировать нельзя.

  • Fragment#isRemoving работает вдвойненеправильно.
  • DialogFragment неправильно работает c retainInstance.
  • SparseArray не проверяет границы переданного индекса при чтении.

Ясное дело, баги есть в любом софте. Только здесь понятие бага очень расплывчато.

Утечки памяти в Andro >
  • Переводы, 12 августа 2020 в 21:06
  • Ярослав Сарницкий


В статье мы расскажем, что такое утечка памяти, как происходит и какие вызывает последствия для операционной системы Android. Также рассмотрим инструменты для обнаружения утечек памяти, типовые модели утечки памяти в Android, способы оценки степени критичности и методы предотвращения основных видов утечек.

Каждому приложению для нормальной работы нужна оперативная память. Для обеспечения необходимым количеством памяти всех приложений Android должен эффективно управлять выделением памяти под каждый процесс. Среда выполнения Android запускает сборку мусора (GC), когда оперативная память заканчивается.

Что такое сборщик мусора?

Java Memory Management со встроенным сборщиком мусора является одним из лучших достижений этого языка. Он позволяет разработчикам создавать новые объекты, не заботясь о распределении памяти и ее освобождении, поскольку сборщик мусора автоматически восстанавливает память для повторного ее использования. Это обеспечивает более быструю разработку с меньшим количеством кода, одновременно устраняя утечки памяти и другие проблемы, связанные с ней. По крайней мере, в теории.

По иронии судьбы сборщик мусора Java работает слишком хорошо, создавая и удаляя большое количество объектов. Большинство проблем управления памятью решаются, но часто за счет уменьшения производительности. Создание универсального сборщика мусора, применяемого ко всем возможным ситуациям, привело к сложностям с оптимизацией системы. Чтобы разобраться со сборщиком мусора, нужно сначала понять, как работает управление памятью на виртуальной машине Java (JVM).

Как работает сборщик мусора

Многие считают, что сборщик мусора собирает и удаляет из памяти неиспользуемые объекты. На самом деле сборщик мусора Java делает все наоборот. Живые объекты отмечаются как активные, а все остальное считается мусором. Как следствие, эта фундаментальная особенность может привести ко многим проблемам с производительностью.

Начнем с так называемой кучи (англ. «heap») — области памяти, используемой для динамического распределения ресурсов приложений. В большинстве конфигураций операционная система заранее отдает эту часть под управление JVM во время работы программы. Это приводит к последствиям:

  • создание объекта происходит быстрее, потому что глобальная синхронизация с операционной системой не требуется для каждого отдельного объекта. В процессе выделения памяти под приложение JVM просто фиксирует за задачей определенный участок памяти и перемещает указатель смещения вперед (картинка ниже). Следующее распределение начинается с этого смещения и занимает следующий участок памяти;
  • когда объект больше не используется, сборщик мусора восстанавливает базовое состояние этого участка памяти и повторно использует ее для размещения другого объекта. Это означает, что нет явного удаления и память все еще не будет очищена.

Новые объекты просто размещаются в конце кучи.

Все объекты размещены в куче, управляемой JVM. Каждый элемент, используемый разработчиком, обрабатывается таким образом, включая объекты класса, статические переменные и даже сам код. Пока объект ссылается на что-то, JVM считает его используемым. Когда объект больше не ссылается и, следовательно, недоступен по коду приложения, сборщик мусора удаляет его и восстанавливает неиспользуемую память. Все настолько просто, как и звучит, но возникает вопрос: какова первая ссылка в дереве объектов?

Корни сборщика мусора — начальная позиция всех иерархий (деревьев) объектов

Каждое дерево объектов должно иметь один или несколько корневых объектов. Пока приложение может достичь этих корней, все дерево доступно. Но когда эти корневые объекты считаются доступными? Специальные объекты, называемые корнями сборщика мусора (корни GC, рисунок ниже), всегда доступны, а также любой объект, чьим корнем является корень сборщика мусора.

23 ноября в 10:00, Санкт-Петербург, 1000–2000 ₽

В Java существуют следующие типы корней сборщика мусора:

  • локальные переменные поддерживаются активными благодаря стеку потока. Это фиктивная виртуальная ссылка на объект и, следовательно, она не видна. Для всех целей и задач локальные переменные являются корнями сборщика мусора;
  • активные потоки Java всегда считаются используемыми объектами и поэтому являются корнями сборщика мусора. Это особенно важно для локальных переменных потока;
  • на статические переменные ссылаются их классы. Это делает их де-факто корнями сборщика мусора. Сами классы могут быть собраны сборщиком, что приведет к удалению всех статических переменных, на которые они ссылаются. Это имеет особо важно, когда мы используем серверы приложений, контейнеры OSGi или загрузчики классов в целом.

Корни сборщика мусора — это объекты, которые ссылаются на JVM и, таким образом, остаются в памяти устройства.

Поэтому простое Java-приложение имеет следующие корни сборщика мусора:

  • локальные переменные в главном методе;
  • основной поток;
  • статические переменные главного класса.

Маркировка и сборка мусора

Чтобы определить, какие объекты больше не используются, JVM периодически запускает алгоритм маркировки и сборки мусора:

  1. Алгоритм «проходит» по всей иерархии объектов, начиная с корней сборщика мусора, и отмечает каждый найденный объект как активный.
  2. Вся участки памяти, не содержащие активных объектов (а точнее объектов, которые не были отмечены в предыдущем шаге), восстанавливаются. Они просто обозначаются как свободные.

Сборщик мусора предназначен для устранения причины утечки памяти — недостижимых, но не удаленных объектов в памяти. Однако это работает только для утечек памяти в классическом их понимании. Возможно, что неиспользуемые объекты по-прежнему доступны приложению, потому что разработчик просто забыл очистить ссылки на них. Такие объекты не могут быть собраны сборщиком. Хуже того, такая логическая утечка памяти не может быть обнаружена никаким программным обеспечением.

Когда объекты больше не ссылаются прямо или косвенно на корень сборщика мусора, они будут удалены. Как видно, с классическими утечками памяти хорошо справляется встроенный сборщик мусора. С другими видами утечек памяти поможет справиться другое программное обеспечение, которое будет рассмотрено далее.

Простыми словами, в памяти остаются только те объекты, которые используются пользователем.

Однако, когда код написан плохо, неиспользуемые объекты могут ссылаться на несуществующие объекты, и сборщик мусора отмечает их как активные и не может их удалить. Это и называется утечкой памяти.

Почему утечка памяти — это плохо?

Ни один объект не должен оставаться в памяти дольше, чем нужно. Ведь эти ресурсы могут пригодиться для задач, которые могут иметь реальную ценность для пользователя. В частности, для Android это вызывает следующие проблемы:

Во-первых, когда происходят утечки, доступной для использования памяти становится меньше, что вызывает более частые запуски сборщика мусора. Такие запуски останавливают рендеринг пользовательского интерфейса, а также вызывают остановку других компонентов, необходимых для нормальной работы системы. В таких случаях прорисовка кадра длиться дольше обычных 16 мс. Когда прорисовка опускается до отметки ниже 100 мс, пользователи начнут замечать замедления в работе приложений.

В Android отзывчивость приложений контролируется менеджером активности и менеджером окон. Система откроет диалог ANR (приложение не отвечает) для конкретного приложения, когда будет выполнено одно из следующих условий:

  • приложение не отвечает на нажатие клавиш, или нажатия на экран на протяжении 5 секунд;
  • BroadcastReceiver не завершился на протяжении 10 секунд;

Вряд ли пользователям понравится видеть это сообщение на экранах своего гаджета.

Во-вторых, приложение с утечкой памяти не сможет получить дополнительные ресурсы от неиспользуемых объектов. Оно сделает запрос на выделение дополнительной памяти, но всему есть свой предел. Android откажется выделять больше памяти для таких приложений. Когда это произойдет, приложение просто упадет. Это может вызвать негативные эмоции у пользователей, а они, в свою очередь, могут не только удалить приложение, но и оставить негативные отзывы о нем в магазине приложений.

Как определить утечку?

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

Приложение Leak Canary от Square — хороший инструмент для обнаружения утечек памяти в приложении. Оно создает ссылки на объекты вашего приложения и проверяет, удаляются ли эти ссылки сборщиком мусора. Если нет, тогда все данные записываются в файл .hprof и проводится анализ на наличие утечек памяти. Если утечка все же будет обнаружена, приложение пришлет вам уведомление о том, как это происходит. Рекомендуется использовать это приложение до выпуска в продакшн. Android Studio также имеет удобный инструмент для обнаружения утечек памяти. Если есть подозрения, что часть кода в вашем приложении может вызывать утечку, тогда можно сделать следующее:

  1. Скомпилировать и запустить отладочную версию сборки на эмуляторе или устройстве подключенному к вашему компьютеру;
  2. Перейти к подозрительной операции, затем вернуться к предыдущему действию, которое выведет подозрительную операцию из стека задач;
  3. В Android Studio открыть Android Monitor window → Memory section и нажать на кнопку запуска сборщика мусора (Initiate GC). Затем нажать кнопку Dump Java Heap ;
  4. После нажатия кнопки Dump Java Heap Android Studio откроет файл .hprof . Существует несколько способов проверки утечки памяти через этот файл. Вы можете использовать Analyzer Tasks в правом верхнем углу для автоматического обнаружения утечек. Или же можно переключиться в режим Tree View и найти действие, которое должно быть отключено. Проверяем данные Total Count , и если нашли отличия в данных, значит, что где-то есть утечка памяти.
  5. Как только была обнаружена утечка, нужно проверить дерево ссылок и узнать, какой объект ее вызывает.


Каковы общие схемы утечек?

Есть множество причин, по которым происходит утечка памяти в Android. Но все они могут быть отнесены к трем категориям.

  • утечки памяти, инициируемые статической ссылкой;
  • утечки памяти, инициируемые рабочим процессом;
  • просто утечка.

Можно загрузить приложение SinsOfMemoryLeaks, которое поможет определить, где происходит утечка.

В ветке Leak будут видны причины утечки памяти. Это приложение можно также запустить на устройстве или эмуляторе и использовать вышеупомянутые инструменты для отслеживания утечек. В ветке FIXED можно увидеть советы, как исправить утечки. После исправления процедуру можно повторить заново, чтобы окончательно убедиться в том, что утечки исправлены. Каждая из веток приложения имеет разные идентификаторы приложений, поэтому вы можете установить их на одном устройстве и проверять показания одновременно.

А теперь быстро пройдемся по всем видам утечек.

Утечки памяти, инициируемые статической ссылкой

Статическая ссылка сохраняется до тех пор, пока ваше приложение находится в памяти. У операций есть свои жизненные циклы, которые прекращаются и начинаются во время работы с приложением. Если вы обращаетесь к операции прямо или косвенно со статической ссылки, сборщик мусора не очистит занимаемую память после завершения операции. Память, занимаемая определенной операцией, может варьировать от нескольких килобайт до нескольких мегабайт в зависимости от того, в каком состоянии находится приложение. Если у него большая иерархия представлений или изображения с высоким разрешением, это может привести к утечке большого количества памяти.

Некоторые особенности утечек для этой категории:

Утечки памяти, инициируемые рабочим процессом

Рабочий поток также может работать дольше, чем нужно. Если сделать ссылку на операции прямо или косвенно из рабочего потока, который живет дольше, чем сами операции, это вызовет утечку памяти. Некоторые особенности утечек для этой категории:

Тот же принцип применяется к таким потокам, как thread pool или ExecutorService .

Просто утечка

Каждый раз при запуске рабочего потока из операции вы сами отвечаете за управление потоком. Поскольку рабочий поток может работать дольше самой операции, нужно остановить его, когда действие будет прекращено. Если этого не сделать, существует вероятность утечки памяти рабочего процесса. Как в этом репозитории.

Каково влияние конкретной утечки?

В идеале следует избегать написания кода, который может вызвать утечку памяти, и исправить все утечки, существующие в приложении. Но на самом деле, если нужно работать со старой базой кода и определить приоритеты задач, включая исправление утечек памяти, можно оценить степень серьезности в следующих аспектах.

Насколько велика утечка памяти?

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

Как долго длится утечка?

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

Сколько объектов в утечке?

В некоторых случаях утечку порождает только один объект, например, один из примеров статических ссылок, показанный в приложении SinsOfMemoryLeaks. Как только будет создано новое действие, оно начнет ссылаться на новую операцию. Старая утечка будет очищена сборщиком мусора. Таким образом, максимальная утечка всегда равна размеру одного экземпляра операции. Однако другие утечки продолжают просачиваться в новые объекты по мере их создания. В примере Leaking Threads активность пропускает по одному потоку каждый раз при его создании. Поэтому, если вы поворачиваете устройство 20 раз, утечка составит 20 рабочих потоков. Это закончится весьма печально, так как приложение заполнит всю доступную память на устройстве.

Как исправить и предотвратить утечки

Посмотрите как происходит устранение типичных утечек памяти в этой ветке репозитория. Решения можно обобщить до следующих пунктов:

  1. Нужно быть очень осторожными, принимая решение установки статической переменной для рабочего процесса. Это действительно необходимо? Возможно, эта переменная ссылается на процесс напрямую или косвенно (ссылка на объект внутреннего класса, прикрепленный экран и т. д.)? Если да, возможно ли будет очистить отсылку к процессу, используя функцию onDestroy ?
  2. Если было решено передавать операцию как синглтон или x-manager , нужно понимать, что делает другой объект с экземпляром действия. Нужно очистить ссылку (установить в null), если необходимо, используя для этого процесса функцию onDestroy .
  3. При создании класса внутри процесса, по возможности старайтесь сделать его статическим. Внутренние классы и анонимные классы имеют неявную ссылку на родительский класс. Поэтому, если экземпляр внутреннего/анонимного класса живет дольше, чем родительский класс, могут возникнуть проблемы. Например, при создании анонимного класса runnable и передаче его в рабочий поток или класс анонимного обработчика и использования его для передачи задач в другой поток существует риск утечки содержащегося объекта класса. Чтобы избежать риска утечки, нужно использовать статический класс, а не внутренний/анонимный класс.
  4. Если писать синглтон или x-manager класс, нужно сохранить ссылку на экземпляр слушателя (англ. «listener»). При этом вы не контролируете, что происходит со ссылкой (удалил ее пользователь класса или нет). В этом случае можно использовать WeakReference для создания ссылки на экземпляр слушателя. WeakReference не мешает сборщику мусора производить свои действия. Хотя эта функция отлично подходит для предотвращения утечек памяти, она также может вызвать побочный эффект, потому что нет гарантии, что ссылочный объект является активным, когда это необходимо. Поэтому рекомендуется использовать его в качестве последнего средства для исправления утечек памяти.
  5. Всегда нужно завершать рабочие потоки, инициированные функцией onDestroy() .

Не забудьте проверить примеры кода для типичных утечек памяти и способы их избежания в репозитории на Github.

Многозадачность в Andro > 31.08.2020 в 21:20

Случай 1. Выполнение запроса по сети, без необходимости ответа от сервера

Иногда вы можете отправить запрос API на сервер, не беспокоясь о его ответе. Например, вы можете отправлять токен устройства для пуш-уведомлений на ваш сервер.

Т.к. это включает в себя создание запроса по сети, вы должны сделать это из потока, отличного от основного.

Вариант 1. AsyncTask или загрузчики

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

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

Вариант 2. Service

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

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

Это потребует больше усилий, чем это необходимо для такого простого действия.

Вариант 3. IntentService

Это, на мой взгляд, было бы лучшим вариантом.

Поскольку IntentService не привязан к какой-либо активности и работает на потоке, отличном от UI, он отлично удовлетворяет нашим потребностям. Кроме того, IntentService автоматически останавливается, поэтому нет необходимости вручную управлять им.

Случай 2. Выполнение сетевого вызова и получение ответа от сервера

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


Вариант 1. Service или IntentService

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

Вариант 2. AsyncTask или загрузчики

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

Однако при использовании AsyncTask или загрузчиков вы заметите, что необходимо написать шаблонный код. Более того, обработка ошибок становится основной задачей этих компонентов. Даже при простом сетевом вызове вам нужно знать о возможных исключениях, ловить их и действовать соответственно. Это заставляет нас обернуть наш ответ в кастомном классе, содержащем данные, с возможной информацией об ошибке, а флаг будет указывать, было ли действие успешным или нет.

Это довольно много работы для каждого вызова. К счастью, теперь доступно гораздо лучшее и простое решение: RxJava.

Вариант 3. RxJava

Возможно вы слышали о библиотеке RxJava, разработанной Netflix. Это почти волшебство на Java.

RxAndroid позволяет использовать RxJava в Android и позволяет работать с асинхронными задачами. Вы можете узнать больше о RxJava на Android здесь. RxJava предоставляет два компонента: Observer и Subscriber .

Наблюдатель — это компонент, который содержит какое-то действие. Он выполняет это действие и возвращает результат, если он удался, ошибка, если он не работает.

Подписчик, с другой стороны, является компонентом, который может получить результат (или ошибку) от наблюдаемого, подписавшись на него.

В RxJava вы сначала создаете наблюдателя:

Как только наблюдатель будет создан, вы можете подписаться на него.

С помощью библиотеки RxAndroid вы можете контролировать поток, в котором вы хотите выполнить действие наблюдателя, и поток, в котором вы хотите получить ответ (т. е. результат или ошибку).

Вы связываетесь с наблюдателем этими двумя функциями:

Планировщики — это компоненты, которые выполняют действие в определенном потоке. AndroidSchedulers.mainThread() — это планировщик, связанный с основным потоком.

Учитывая, что наш вызов API — это mRestApi.getData() , и он возвращает объект Data, базовый вызов может выглядеть так:

Даже не вникая в другие преимущества использования RxJava, вы уже можете видеть, как RxJava позволяет нам писать более зрелый код, абстрагируя сложность потоковой передачи.

Случай 3. Цепочка сетевых вызовов

Для сетевых вызовов, которые необходимо выполнить последовательно (т.е. когда каждая операция зависит от ответа / результата предыдущей операции), вам нужно быть особенно осторожным при создании спагетти кода.

Например, вам может потребоваться выполнить запрос к API с помощью токена, который вам нужно сначала получить через другой запрос к API.

Вариант 1. AsyncTask или загрузчики

Использование AsyncTask или загрузчиков почти наверняка приведет к спагетти коду. Общую функциональность будет трудно реализовать правильно, и для вашего проекта потребуется огромное количество избыточного шаблонного кода.

Вариант 2. RxJava с использованием flatMap

В RxJava оператор flatMap берет исходящее значение из наблюдаемого источника и возвращает другого наблюдателя. Вы можете создать одного наблюдателя, а затем другого, и использовать исходящее значение из первого, для их связи.

Шаг 1. Создайте наблюдателя, который извлекает токен:

Шаг 2. Создайте наблюдателя, который получает данные с помощью токена:

Шаг 3. Цепочка двух наблюдателей вместе и подписка:

Обратите внимание, что использование этого подхода не ограничивается сетевыми вызовами; Он может работать с любым набором действий, которые должны выполняться в последовательности, но в отдельных потоках.

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

Случай 4. Общение c UI потоком из другого потока

Рассмотрим сценарий, в котором вы хотите загрузить файл и обновить пользовательский интерфейс после его завершения.

Поскольку загрузка файла может занять много времени, нет необходимости держать пользователя в ожидании. Вы можете использовать сервис и, возможно, IntentService для реализации функциональности в нем.

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

Вариант 1. RxJava внутри сервиса

RxJava, как самостоятельно, так и внутри IntentService , может быть не идеальным решением. Вам нужно будет использовать механизм обратного вызова при подписке на Observable , а IntentService построен для выполнения простых синхронных, а не обратных вызовов.

С другой стороны, с помощью Service вам необходимо будет вручную остановить службу, что потребует дополнительной работы.

Вариант 2. BroadcastReceiver

Android предоставляет компонент, который может слушать глобальные события (например, события батареи, сетевые события и т.д.), А также настраиваемые события. Вы можете использовать этот компонент для создания настраиваемого события, которое запускается при завершении загрузки.

Для этого вам нужно создать собственный класс, который расширяет BroadcastReceiver , регистрирует его в манифесте и использует Intent и IntentFilter для создания настраиваемого события. Чтобы инициировать событие, вам понадобится метод sendBroadcast .

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

Вариант 3. Использование Handler

Handler — это компонент, который может быть присоединен к потоку, а затем быть использованным для выполнения некоторых действий в этом потоке с помощью простых сообщений или Runnable задач. Он работает совместно с другим компонентом — Looper , который отвечает за обработку сообщений в конкретном потоке.


Когда Handler создается, он может получить объект Looper в конструкторе, который указывает, к какому потоку он прикреплен. Если вы хотите использовать Handler, прикрепленный к основному потоку, вам нужно использовать looper, связанный с основным потоком, вызывая Looper.getMainLooper() .

В этом случае для обновления пользовательского интерфейса из фонового потока вы можете создать Handler, подключенный к потоку пользовательского интерфейса, а затем опубликовать действие как Runnable :

Этот подход намного лучше, чем первый, но есть еще более простой способ сделать это…

Вариант 3. Использование EventBus

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

Шаг 1. Создайте класс событий. Например, UIEvent .

Шаг 2. Подпишитесь на событие.

Шаг 3. Отправьте событие: EventBus.getDefault (). Post (новый UIEvent ());

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

Вы можете структурировать свой класс UIEvent , чтобы он содержал дополнительную информацию по мере необходимости.

В активности / фрагменте:

Используя библиотеку EventBus , связь между потоками становится намного проще.

Случай 5. Двусторонняя связь между потоками на основе действий пользователя

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

Полный пример медиаплеера выходит за рамки этой статьи. Однако вы можете найти хорошие материалы здесь и здесь.

Вариант 1. Использование EventBus

Здесь вы можете использовать EventBus . Однако, как правило, не безопасно отправлять событие из потока пользовательского интерфейса и получать его в сервисе. Это связано с тем, что вы не можете узнать, работает ли сервис, когда вы отправили сообщение.

Вариант 2. Использование BoundService

BoundService — это служба, связанная с активностью / фрагментом. Это означает, что активность / фрагмент всегда знает, работает служба или нет и получает доступ к публичным методам службы.

Чтобы реализовать его, вам необходимо создать настраиваемый Binder внутри службы и создать метод, который возвращает службу.

Чтобы связать активность со службой, вам необходимо реализовать ServiceConnection , который является классом, контролирующим статус службы, и использовать метод bindService для привязки:

Здесь вы можете найти полный пример реализации.

Чтобы связаться со службой, когда пользователь нажимает кнопку «Воспроизведение» или «Пауза», вы можете привязать их к службе, а затем вызвать соответствующий общедоступный метод в службе.

Когда есть мультимедийное событие, и вы хотите сообщить об этом активности / фрагменту, вы можете использовать один из более ранних подходов (например, BroadcastReceiver, Handler или EventBus).

Случай 6. Выполнение действий параллельно и получение результатов

Предположим, вы строите туристическое приложение, и вы хотите показать достопримечательности на карте, полученные из нескольких источников (разные поставщики данных). Поскольку не все источники могут быть надежными, вы можете проигнорировать те, которые потерпели неудачу, и продолжать отображать карту в любом случае.

Чтобы распараллелить процесс, каждый вызов к API должен выполняться в другом потоке.

Вариант 1: Использование RxJava

В RxJava вы можете комбинировать несколько наблюдателей в одном с помощью операторов merge() или concat() . Затем вы можете подписаться на «merged» наблюдатели и ждать всех результатов.

Но, этот подход не будет работать должным образом. Если один вызов к API завершится неудачно, объединенный (merged) наблюдатель сообщит об общем сбое.

Вариант 2. Использование Java-компонентов

ExecutorService в Java создает фиксированное (настраиваемое) количество потоков и одновременно выполняет задачи на них. Служба возвращает объект Future , который в конечном итоге возвращает все результаты с помощью метода invokeAll() .

Каждая задача, которую вы отправляете в ExecutorService , должна содержаться в интерфейсе Callable , который является интерфейсом для создания задачи, которая может генерировать исключение.

Получив результаты от invokeAll() , вы можете проверить каждый результат и действовать соответствующим образом.

Скажем, например, что у вас есть три типа данных, поступающих из трех разных конечных точек, и вы хотите сделать три параллельных вызова:

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

Этот подход проще, чем использование RxJava. Это проще, короче и не отменяет все действия из-за одного исключения.

Случай 7. Запрос к локальной SQLite базе данных

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

При запросе данных из SQLite вы получаете объект Cursor , который затем может использоваться для получения фактических данных.

Вариант 1: Использование RxJava

Вы можете использовать RxJava и получать данные из базы данных, так же, как мы получаем данные из нашего back-end:

Вы можете использовать наблюдателя, возвращаемого getLocalDataObservable() следующим образом:

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


Вариант 2: Использование CursorLoader + ContentProvider

Android предоставляет CursorLoader , собственный компонент для загрузки данных из SQLite и управления соответствующим потоком. Это Loader , который возвращает Cursor , который мы можем использовать для получения данных, вызывая простые методы, такие как getString() , getLong() и т.д.

CursorLoader работает с компонентом ContentProvider . Этот компонент предоставляет множество возможностей для работы с базой данных в режиме реального времени (например, уведомления об изменениях, триггеры и т.д.), что позволяет разработчикам более легко реализовать более удобный пользовательский интерфейс.

Заключение

Android предоставляет множество способов обработки и управления потоками, но ни один из них не является серебрянной пулей.

Выбор правильного подхода к многопоточности, в зависимости от вашего варианта использования, может сделать все возможное, чтобы общее решение было легко реализовано и понято. Нативные компоненты подходят для некоторых случаев, но не для всех. То же самое относится к причудливым сторонним решениям.

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

Делаем правильную множественную загрузку в Andro >

В одном из наших приложений была поставлена задача загружать иконки приложений, которые имеются на устройстве. Поскольку иконок, как и приложений, может быть очень много, для повышения быстродействия эту операцию следовало разделить на параллельные процессы. Затем загруженные записи с приложениями и иконками выводятся пользователям с помощью RecyclerView.

Для выполнения этих задач используется класс AsyncTask, принимающий в качестве исходных данных ID ImageView, в который нужно загрузить иконку, и выполняющий процесс загрузки.

Сейчас код, реализующий загрузку иконок, выглядит следующим образом:

Однако, как оказалось, здесь имеется существенный недостаток: AsyncTask вместо того, чтобы для загрузки каждой иконки выделять отдельный поток, выполняет все операции в одном потоке, выстраивая их в очередь выполнения. То есть, при создании нового ViewHolder или его перебиндивания вызываемый AsyncTask не запускает новый поток, а ждёт, пока не будет выполнен работающий AsyncTask. Как следствие, загрузка иконок может занять много времени, и также это может вызвать дерганье интерфейса на слабеньких устройствах.

Такая проблема возникает потому, что, начиная с версии Android 3.2 Honeycomb, класс AsyncTask перестал создавать поток для каждого экземпляра, вместо этого создаётся объект Executor, который выполняет всё в одном фоновом потоке. Из-за этого сейчас крайне не рекомендуется его использовать для операций, выполняющихся не один раз, а на протяжении долгого времени.

Чтобы исправить проблему, попробуем создать собственный фоновый поток для загрузки иконок. В этом нам поможет класс HandlerThread, благодаря которому мы создадим цикл сообщений. Фоновый поток с помощью очередей будет проверять новые сообщения, а главный поток будет извлекать эти сообщения из очереди.

Старый код убираем полностью, теперь наш класс GetIconTask будет наследовать от HandlerThread, а не от AsyncTask.

Обобщённый параметр T используется для того, чтобы реализация была более гибкой, не привязанной к какому-то конкретному типу. Метод queueIcon() будет принимать имя пакета, иконку которого мы хотим загрузить в потоке. Он будет вызываться там же, где сейчас запускается AsyncTask, то есть в методе onBindViewHolder() адаптера.

Теперь нужно фоновый поток запускать. Запускаться он будет в момент старта приложения и останавливаться, если оно было закрыто. Поэтому нам нужны методы главной активности onCreate() и onDestroy() соответственно.

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

Теперь в методе onBindViewHolder() передаём в метод queueIcon() фонового потока сам холдер и имя пакета. Чтобы получить доступ к экземпляру GetIconTask, нужно будет передать его в адаптер через конструктор.

На данном этапе фоновый поток уже должен получать сообщения от адаптера, однако он их пока никак не обрабатывает. Для того, чтобы реализовать обработку, нам понадобится класс Handler, отвечающий за обработку и отправку сообщений (Message). В данной реализации сообщения будут создаваться и отправляться в конец очереди Looper, откуда уже Handler будет его обрабатывать. Для того, чтобы добавить сообщения в очередь, нам также понадобится константа, определяющая сообщение (поле what).

Для хранения имён пакетов используется безопасная разновидность HashMap — ConcurrentHashMap, принимающая в качестве ключа объект T.

Теперь сообщение нужно отправить в очередь, для этого дополним код в методе queueIcon().

Здесь сообщение отправляется на приёмник для дальнейшей обработки. Теперь нашему Handler нужно извлечь сообщение из очереди и загрузить иконку, выполнив необходимые операции. Для этого переопределим метод onLooperPrepared(), в котором Handler будет извлекать сообщения и обрабатывать их в отдельном методе.

Фоновый поток принимает и обрабатывает сообщения, однако главный поток об этом ничего не знает. Чтобы передать сообщение в главный поток, нужно объявит в нём экземпляр Handler, который будет передаваться в конструктор фонового потока. В фоновом же потоке нужно добавить интерфейс, через который главный поток будет принимать ViewHolder и иконку приложения.

Метод onIconDownloaded() в интерфейсе будет вызываться тогда, когда иконка будет загружена и готова к добавлению.

Теперь нам нужно передать Handler из главного потока, для этого нужно его объявить, также необходимо установить слушатель, который будет принимать готовые иконки и обновлять нужные холдеры.

Связь между двумя потоками установлена, но никакие данные между ними не пересылаются. Чтобы отправить сообщение из фонового потока в главный, нужно в методе handleRequest() фонового потока добавить код, передающий сообщение в интерфейс и удаляющий его из очереди.

Благодаря условию внутри run() мы можем быть уверены, что каждое приложение в списке получит свою иконку.

Чтобы обезопасить себя от возможных ошибок с утечкой памяти или удалением связи между GetIconTask и адаптером, нужно реализовать полную очистку списка. Для этого в классе GetIconTask добавляем новый метод clearQueue().

Затем в методе нашей активности onStop() вызываем очистку списка.

В результате у нас получилась множественная загрузка иконок без каких-либо подтормаживаний и багов. Фоновый поток обрабатывает получаемые сообщения и возвращает их главному потоку, откуда уже происходит обновление записей в RecyclerView. Итоговый код класса GetIconTask выглядит следующим образом:

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

Вот так работает загрузка иконок с использованием AsyncTask.

А вот так — после замены AsyncTask на HandlerThread.

Подводя итоги, можно сказать, что использование AsyncTask для часто повторяющихся операций не является эффективным решением, хотя в некоторых ситуациях этот класс крайне полезен, поскольку очень прост в реализации. С помощью HandlerThread же мы добились того, что приложение стало работать быстрее, чем раньше, что должно положительно сказаться на отзывах пользователей.

Скачать обновлённый Менеджер системных приложений вы можете в Google Play по следующей ссылке.

Делаем правильную множественную загрузку в Android : 4 комментария

» эту операцию следовало разделить на параллельные процессы. » — вот после этой фразы сразу закрались сомнения..

Вы просто накидываете в свой Looper сообщения в очередь, по очереди их обрабатываете и отравляете в Main Looper — где тут множетвенная загрузка и распараллеливание?

У вас API > 16? Чем не нравится AsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) — сам все распараллелит и не надо столько кода впустую писать. Не нравится TREAD_POOL_EXECUTOR? — можно свой написать — и то в разы проще будет.

Ну если хочется совсем хардкора — можно использовать «родные» способы распараллеливания java, например ExecutorService:

ExecutorService executionService = Executors.newFixedThreadPool(5);
executionService.submit(new Runnable(. ))
.
executionService.shutdown();

и это, в принципе, 3 сточки которые заменят почти всю вашу реализацию.


Спасибо за комментарий. У нас апи 14 минимальный.

Да, и картинки у вас с AsyncTask менялись вовсе не потому, что AsyncTask выполнял все поочередно, а оптому что вы передаете ImageView в каждый таск, RecyclerView — переиспользует ваши вьюхи, и все накиданные ранее таски просто сетили свои картики по завершению во вьюху, вам надо лишь было отменять предыдущий AsyncTask при новом onBind

Как устранить неполадки в работе приложений Andro >

Если приложение работает со сбоями, не открывается или не реагирует на команды, воспользуйтесь приведенными ниже инструкциями. После каждого шага проверяйте, удалось ли устранить неполадку.

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

Совет. Если проблема возникает в приложении с мгновенным запуском, воспользуйтесь инструкциями по устранению неполадок.

Шаг 1. Перезагрузите устройство и обновите ПО

Чтобы перезагрузить телефон, удерживайте кнопку питания в течение нескольких секунд. Затем нажмите «Перезапустить» .

Если такого варианта нет на экране, удерживайте кнопку питания около 30 секунд до перезагрузки телефона.

Проблему может решить обновление системы.

Чтобы проверить наличие обновлений и установить их, выполните следующие действия:

  1. Откройте настройки телефона.
  2. В нижней части списка выберите Система » title=»>»> Расширенные настройки » title=»>»> Обновление системы. При необходимости сначала выберите О телефоне или О планшете.
  3. Вы увидите статус обновления. Следуйте инструкциям на экране.

Проблему может решить обновление приложений.

Чтобы найти и установить обновления, выполните следующие действия:

  1. Запустите приложение «Google Play Маркет» на телефоне.
  2. Нажмите на значок меню » title=»>»>Мои приложения и игры.
  3. Рядом с приложениями, для которых доступны обновления, будет пометка «Обновить».
    • Выберите нужное приложение и нажмите Обновить.
    • Чтобы установить обновления для всех приложений, выберите Обновить все.

Шаг 2. Устраните сбой в приложении

Обычно закрывать приложения не требуется, поскольку Android управляет тем, как приложения используют память устройства.

Но при необходимости вы можете полностью закрыть приложение, включая все его фоновые процессы.

  1. Откройте приложение «Настройки» .
  2. Нажмите Приложения и уведомления.
  3. Выберите приложение. Если его нет в списке, сначала нажмите Показать все приложения или Сведения о приложениях.
  4. Нажмите Остановить.

Если после этого проблема не исчезнет, свяжитесь с разработчиком приложения. Подробнее…

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

Чтобы очистить кеш приложения, выполните следующие действия:

  1. Откройте настройки устройства .
  2. Нажмите Приложения и уведомления.
  3. Выберите приложение. Если его нет в списке, сначала нажмите Показать все приложения или Сведения о приложениях.
  4. Нажмите Память » title=»>»>Очистить кеш.

Если проблема не исчезнет, свяжитесь с разработчиком приложения. Подробнее…

Иногда для устранения неполадки нужно удалить все данные приложения.

Внимание! Все данные, сохраненные в приложении, будут удалены.

Чтобы стереть данные, сделайте следующее:

  1. Откройте настройки устройства .
  2. Нажмите Приложения и уведомления.
  3. Выберите приложение. Если его нет в списке, сначала нажмите Показать все приложения или Сведения о приложениях.
  4. Выберите Память » title=»>»>Очистить данные или Стереть данные » title=»>»>OK.

Если проблема не исчезнет, свяжитесь с разработчиком приложения. Подробнее…

Если вы скачали приложение из Google Play:

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

Если в работе приложения все равно возникают сбои, вы можете его удалить.

Внимание! Все данные, сохраненные в приложении, будут удалены.

Чтобы удалить приложение, выполните следующие действия:

  1. Нажмите и удерживайте значок приложения, которое хотите удалить.
  2. Перетащите приложение к надписи Удалить в верхней части экрана. Если такой надписи нет , скорее всего, это системное приложение, которое невозможно удалить.

Чтобы снова использовать приложение, попробуйте переустановить его. Подробнее…

Threads, AsynkTask, Handler


check if currents thread is main thread in Android

//усыпляем текущий поток

Handler создается в основном потоке, и к нему можно обратиться из побочного, а Handler в свою очередь может общаться с UI.

При использовании Handler важно не допустить утечку памяти. См здесь.

Получить доступ к Handler из какого-либо другого потока мы сможем без проблем, т.к. основной поток монополизирует только доступ к UI. А элементы классов (в нашем случае это Handler в MainActivity.java) доступны в любых потоках.

Сообщение может содержать в себе атрибуты.

Handler также может использовать для обработки сообщений объект, реализующий интерфейс Handler.Callback

Кроме обработки сообщений, мы можем попросить Handler выполнить кусок кода – Runnable , который так же будет иметь доступ к UI

Еще несколько способов выполнения кода в UI потоке

String. strings — это типа массив неизвестной длины

The three types used by an asynchronous task are the following: AsyncTask

  1. Params , — тип параметра, массива. принемаегого в doInBackground .
  2. Progress , — тип параметра, который метод publishProgress передает в onProgressUpdate
  3. Result — тип объекта, который возвращает doInBackground , и он попадает параметром в onPostExecute

Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:

Вариант получения результата Asynk Task’a с помощью метода get()

Отмена Task’a

returns false if the task could not be cancelled, typically because it has already completed normally; true otherwise

Статус AsynkTask’a

  • PENDING — задача создана, но еще не запущена
  • RUNNING — выполняется или . отменена (видимо баг)
  • FINISHED — завершена (не отменена)

Looper, HandlerThread, etc

пример с HandlerThread, Handler, Looper Кажется, что передавая Looper полученный из worker потока (handlerThread.getLooper) в конструктор Handler’a, мы заставляем обрабатывать в порядке очереди сообщения, отправленные из UI потока в хэндлер, в worker потоке, которому принадлежит Looper.

Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

Тогда наверное, при создании хэндлера в Activity, когда мы хотим посылать в активити сообщения из worker потока. Хэндлер берет Looper из Activity, из UI Thread, и соответственно выполняет полученные сообщения по очереди в UI Thread;

«внутри лупера для каждого потока, который запросил у него какой то метод, создается очередь сообщений. Если посмотреть чуть ниже, то это класс МсжКью, представляет собой наполовину Java наполовино нативную очередь сообщений. Он как раз таки обрабатывает объекты Message» — с Droidcoin’a

Solution with Handler in Present Project

Проблемы ОС Andro >

Допустим, мы все – большие фанаты ОС Android и даже помыслить не можем о переходе на другую операционную систему. Тем не менее, даже в этом случае мы не сможем поспорить с тем, что совершенным Android назвать нельзя, и пользователям время от времени приходится сталкиваться с рядом типичных проблем. Некоторые из них связаны с конкретными устройствами, какие-то обусловлены особенностями самой ОС. Мы поговорим об общих проблемах, с которыми приходится иметь дело пользователям Android, а также о возможных способах их решения.

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

1. Проблемы с аккумулятором

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

Возможное решение

Когда речь идет о стремительном разряде аккумулятора, вы можете посмотреть, какие приложения расходуют его сильнее, для этого нужно зайти в раздел Батарея в меню Настройки. Если вы видите, что какое-то приложение расходует необычно много заряда, лучше всего его удалить. Если это нельзя сделать, можно понадеяться на то, что проблему исправят вместе с обновлением. Убедитесь, что у вас стоит последняя версия этого приложения.

Если аккумулятор вашего устройства не работает так же, как год или даже полгода назад, когда он был новым, волноваться не стоит. Впрочем, можно заставить его протянуть дольше, выполняя простейшие действия – снизить уровень яркости дисплея, оптимально настроить режим энергосбережения или использовать специальные приложения, позволяющие оптимизировать энергопотребление вашего устройства.

2. Проблемы с производительностью

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

Возможное решение

И тут на помощь могут прийти менеджеры приложений типа Greenify. Скачав его, вы увидите список приложений, которые активны при включении устройства, вы можете поменять настройки для этих приложений, и таким образом они перестанут замедлять работу.

Причиной проблем с производительностью может быть и вредоносное приложение. Загрузите устройство в безопасном режиме (то, как это сделать, различается в зависимости от устройства) и посмотрите, сохраняется ли проблема. Если нет, виновато действительно приложение, и тогда есть два способа решения. Первый – удалить последние установленные приложения. Второй – сбросить устройство к заводским настройкам – это, конечно, крайний случай, поскольку вы потеряете всю свою информацию. Так что, собираясь сбросить устройство, проверьте, все ли нужные файлы вы сохранили.

3. Проблемы с подключением


Приобретая новое устройство, вы можете неожиданно столкнуться с проблемами подключения по Wi-Fi and Bluetooth. Есть ряд проблем, связанных с конкретными устройствами, но ниже описаны общие решения – те, которые стоит попробовать в первую очередь.

Возможное решение

Проблемы с Wi-Fi

  • Выключите устройство и роутер по меньшей мере на 10 секунд, затем включите и повторите попытку подключения.
  • Зайдите в Настройки – Энергосбережение и убедитесь, что эта опция отключена.
  • Используйте Wi-Fi Analyzer и проверьте, насколько забит ваш канал, поищите лучший вариант.
  • «Забудьте» подключение, для этого зайдите в Настройки – Wi-Fi, долгий тап по нужной сети и выберите «Забыть». Затем подключитесь снова.
  • Проверьте, не устарел ли ваш роутер.
  • Проверьте ПО на самом устройстве, убедитесь, что оно не устарело.
  • Зайдите в Wi-Fi – Настройки – Дополнительно и проверьте, разрешен ли доступ MAC адресу вашего устройства в MAC фильтре роутера.

Проблемы Bluetooth

  • Если они связаны с подключением к машине, сверьтесь с инструкцией производителя и обновите подключение
  • Проверьте, не пропустили ли вы необходимый шаг в процессе подключения
  • Зайдя в Настройки – Bluetooth, проверьте, не нуждается ли что-то в зарядке
  • Зайдя в Настройки – Bluetooth, удалите все предшествующие настройки подключения устройств и проведите «спаривание» с чистого листа.
  • Если возникла проблема с множественным подключением устройств, ее может устранить только будущее обновление.

4. Проблемы с агрессивным энергосбережением

В каждом Android смартфоне есть тот или иной режим энергосбережения, а если ваше устройство имеет на борту Android 6.0 Marshmallow или выше, в нем также имеется и режим Doze. Это очень полезно, когда вам требуется выжать максимум из аккумулятора, но вместе с тем может возникнуть проблема пропуска уведомлений.

Возможное решение

Если вы с этим столкнулись и уведомления от приложений, таких как Gmail, Whatsapp, Facebook, приходят с задержкой или вообще не поступают, вам стоит перенести эти приложения в разделе Батарея в список не подлежащих оптимизации. На некоторых устройствах это будет меню Настройки – Настройки батареи (три вертикальные точки) – Оптимизация батареи, открываете «Все приложения» в выпадающем меню, идете в нужное приложение и тапаете «Не оптимизировать». Если этот список не будет особенно расширяться, вы не увидите никаких заметных последствий для времени жизни батареи.

5. Проблемы с Google Play Store

Практически на любом Android смартфоне за пределами Китая предустановлен Google Play Store, и именно там мы добываем нужные нам приложения. Однако бывают ситуации, в которых Google Play Store перестает работать как надо.

Возможное решение

Универсального способа решить проблему с Google Play Store не существует. Но вам стоит в первую очередь убедиться, что дело именно в вашем устройстве, а не в сервисах Google. После этого возможны несколько шагов: принудительное закрытие приложение, очистка кэша Play Store, проверка того, какие приложения или сервисы, будучи отключенными, повлияли на работу магазина приложений, и многое другое. Наконец, можно попробовать вернуть Google Play Store к более старой версии (Настройки – Приложения – Google Play Store – Удалить обновления), а потом снова обновить приложение.

Android — android проблема с Handler!

-Все посты содержания «Когда появится список для прошивки ***» или же «Составьте барину список для устройства ***» будут удаляться. Научитесь пользоваться поиском по форуму в целом, и по данной теме в частности.
-Перед любыми действиями по удалению/замене/редактированию системных приложений делайте бэкап прошивки через рекавери. Также рекомендуется замораживать приложения в ® Titanium Backup перед их удалением. В случае неудачного удаления восстановить резервную копию заметно проще чем искать по форуму нужные файлы. Ни автор, ни кто-то другой не несет ответственности за ваше устройство.

  • Не забывайте о том, что в теме действуют Правила форума 4PDA .
  • В данной теме обсуждаются только системные приложения и всё, что связано с их удалением. Обсуждение стороннего софта запрещено .
  • Вопросы, ответы и пояснения на которые есть в шапке темы, будут удаляться.
  • Если вы пишите о проблеме, возникшей вследствие удаления системного ПО, постарайтесь максимально подробно описать эту проблему и укажите название устройства и версию установленной прошивки.
  • Если вы выложили полезную информацию, которую по вашему мнению следует добавить в шапку, обратитесь к куратору темы в ЛС. После просмотра будет принято решение поднимать её в шапку или нет.
  • Здесь не выкладывают .apk и .odex файлы системных приложений, в случае необходимости обращайтесь в тему обсуждения прошивок для вашего устройства в разделе Android — Прошивки.
  • В этой теме не обсуждаются проблемы, связанные с перепрошивкой, установкой кастомных рекавери и т.д. Подобные вопросы следует задавать в разделе Android — Прошивки.
  • В этой теме не обсуждается редактирование системных приложений (в том числе отвечающих за локскрин или статус-бар). Со всеми вопросами данной тематики обращаться в раздел Android — Украшательства.

Для тех, кто планирует создавать списки удалённых приложений убедительная просьба соблюдать ряд требований, представленных под спойлером ниже:

  1. Обязательно указывайте модель устройства, на котором велось удаление приложений с указанием версии ОС. В случае, если установлен кастом, то указывайте его название.
  2. Обязательно публикуйте только лично проверенную информацию.
  3. Обязательно составляйте список с описанием приложений. «Слепые» списки без описания приложений будут удаляться, поскольку каждый пользователь сам решает какое приложение ему не нужно, а без описания это сделать невозможно.
  4. Желательно указывать критерии очистки системы (пользуетесь ли Вы гуглоаппсами, либо каким-то другим встроенным софтом)

Соблюдение этих правил упростит процесс систематизации информации и её поиска в данной теме.

1. Q: Где находятся стоковые программы и как их удалить?
A: Стоковые (стандартные или заводские) программы находятся в /system/app.
Открыть данную директорию можно при помощи RootExplorer, FileExplorer и подобных ей, а так же Titanium Backup при наличии прав ROOT и монтировании в r/w. Порядок и названия могут отличаться (в Titanium Backup вместо фалов .apk отображаются названия программ). Помните о том, что не обязательно сразу удалять приложение, вы можете его переименовать или заморозить при помощи программы Titanium Backup. В этом случае телефон не распознает переименованный файл как приложение, и вы сможете восстановить/разморозить его в случае необходимости.

2. Q: Какие программы можно удалять?
A: Каждый пользователь должен сам определиться какие системные приложения ему не нужны, далее нужно посмотреть могут ли быть последствия от удаление не нужных вам приложений, если их (последствий) нет, то можно смело удалять эти приложения. А если последствия есть, например некоторые проги имеют зависимости, то нужно подумать удалять вам их или нет, например вам не нужны карты Google и вы ни когда не будите использовать системные и сторонние программы которые используют данные карт гугла, значит вы смело можете удалять эти карты.

3. Q: Где еще остаются файлы от удалённых приложений и нужно ли их удалять?
А: Части программ могут оставаться в data/data, data/dalvik-cache, (system/lib — желательно не трогать, т.к. есть зависимости). Имена файлов не всегда совпадают с названием приложения. Будьте внимательны. Чтоб узнать «внутреннее» имя программы, нужно зайти рутэксплорером в папку, где она лежит, затем короткий тап по апк файлу — нажать view и посмотреть манифест. После удаления желательно сделать ХР. Небольшое пояснение.

4. Q: Можно ли удалять стандартные приложения Google, повлияет ли это на работу аппарата?
A: Приложения (Maps, Gmail, Gtalk и т.д.) можно. Службы нежелательно, так как в случае удаления перестанут работать все гугловские сервисы и приложения, а также возможно появление постоянных ошибок на устройстве.

5. Q: Можно ли удалить стандартные приложения от Google (Навигация, Адреса, Просмотр улиц) отдельно от приложения Карты?
A: Просмотр улиц (Street.apk) можно, а остальные нет, так как они являются частью приложения Карты (Maps.apk).

6. Q: Обязательно ли удалять .odex файлы программы вместе с файлами .apk?
A: Да. Данные файлы являются частью одноименного приложения.

7. Q: Где взять стандартный файл .apk с какой либо прошивки?
A: Пойти в тему про прежнюю прошивку и попросить вырезать Вам этот apk тех, кто еще ей пользуется. Или же распаковать родную прошивку, и вытащить необходимый файл.

8. Q: Удалил ненужные системные приложения, а в диспетчере задач отображаемая память телефона как и была до чистки. В чем загвоздка?
A: Ответ (взаимодействие разделов в Android).

9. Q: Удалил стандартную клавиатуру, после чего не работает SWYPE. Что делать?
A: Сделать SWYPE системным.

10. Q: Установил стороннюю звонилку и при пропущенном звонке в панели уведомлений появляется сразу 2 извещения: от стандартной и сторонней.
A: Решение: сделать стороннюю звонилку системной (я делал это через titanium backup, но подозреваю, что достаточно просто в системную папку apk перенести).

11. Q: Не могу удалить некоторые гугловские приложения; удалил из папки system/app, но они всё равно работают.
A: Возможно эти приложения находятся в папке data/app и удалить их нужно ещё и оттуда.

12. Q: На Samsung Galaxy Gio не могу удалить стоковые приложения: Вешалка, Drive & Walk, Книги.
A: Решение можно найти в шапке темы Samsung GT-S5660 Galaxy Gio — установка и обновление ПО через recovery. Читать информацию под спойлером » Удаление встроенного ПО».

13. Q: Как восстановить системные приложения?
A: Ответ.

14. Q: Можно ли удалить стоковый лаунчер?
A: Можно, но только при наличии стабильно работающего стороннего лаунчера, который желательно сделать системным приложением. Но следует учесть, что не все стандартные виджеты могут работать на стороннем лаунчере.

15. Q: После удаления приложений в меню остаются серые ярлыки удаленных приложений. Как их удалить?
A: Следует очистить данные лаунчера через Настойки (Настройки -> Приложения -> Launcher -> Очистить данные) или через ® Titanium Backup. Следует учесть, что в результате этого слетят все пользовательские настройки рабочего стола (виджеты и т.д.).

16. Q: Как удалить стандартный локскрин?
А: Удалить его очень проблематично (для этого необходимо редактировать несколько системных apk), а отключить можно через Настройки -> Экран Блокировки. Или через ShutdownApp (сервисный код *#7594#; следует учесть, что в этом случае также пропадёт меню перезагрузки).

17. Q: Где найти список приложений для определённого устройства?
A: Ссылки на большинство списков на этом форуме есть под спойлером «Приложения, удалённые на конкретных моделях» . Если этого устройства там нет, то следует просмотреть списки для похожих устройств (от того же производителя и на этой же версии OS).

18. Q: Можно ли создать скрипт, удаляющий приложения, и как это сделать?
A: Да, такие скрипты нередко встречаются в темах обсуждения прошивок. Почитать о создании и редактировании можно здесь.

19. Q: Почему после ребутов удалённые приложения восстанавливаются?
A: Вероятно, для того, чтобы этого не происходило, следует устанавливать кастомные ядра. Какие именно ядра лучше устанавливать и инструкции по установке смотреть в теме прошивок или ядер.

20. Q: После удаления приложения SamsungHub.apk перестал работать автоповорот экрана. Как это исправить?
A: Проблема кроется в удалённом libgnustl_shared.so. Решение этой проблемы написано здесь.

21. Q: Как убрать кнопки «S-voice» и «Быстрое подключение» из шторки?
A: Решение этой проблемы написано здесь.

22. Q: Как посмотреть запущенные фоновые процессы?
A: Включить информационный слой с данными использования ЦП (Настройки-Параметры разработчика-Выводить использование ЦП).

Управление автозапуском
®AutoRun Manager — Менеджер автозагрузки приложений.
® Autostarts — программа для расширенного управления и мониторинга автозапуска ПО
Startup Manager — управление запуском приложений и сервисов.

Мониторинг энергопотребления
GSam Battery Monitor — утилита для мониторинга энергопотребления

Файловые менеджеры с Root доступом
® Root Explorer — файловый менеджер для Root пользователя. Нужно включить режим r/w (в правом верхнем углу)
AROMA Filemanager — файловый менеджер с доступом через рекавери.
EStrongs File Explorer — функция управления системными файлами включается в настройках
® Solid Explorer

Другие
® SystemApp Remover — предназначено для удаления системных приложений.
® Root App Delete — приложение для удаления системных приложений.
® Titanium Backup — программа для резервного копирования приложений и их данных, как системных, так и пользовательских, позволяет удалять системные приложения, преобразовывать сторонние приложения в системные. Есть очень интересная функция — заморозка приложения. Очень удобно использовать при тестах, надо мне определить поведение системы без какого-либо приложения, я просто его замораживаю, провожу тестирование и при выявлении глюков приложение можно разморозить без потери работоспособности. Также в PRO-версии есть функция очистки dalvik-cache.
Universal AndRoot — получение root прав.

ДА – означает, что программа может быть удалена без ущерба для базового функционала. Прежде чем ее удалить, прочтите описание и удостоверьтесь, что она действительно Вам не нужна.
НЕТ – программа необходима для стабильности системы и работоспособности базовых функций устройства.
В этом списке указаны исправления для ICS и Jelly Bean.

AccountAndSyncSettings.apk — НЕТ. параметры синхронизации, необходимое приложение. Данное приложение отвечает не только за синхронизацию контактов и календаря, но и всего остального, связанного с учетной записью Google. Даже если Вы ничего не синхронизируете, не стоит его удалять.
AccuWeatherDaemonService.apk (AccuweatherDaemon.apk (4.x.x)) — ДА. «Демон» в фоновом режиме автоматически обновляет погоду на лок скрине и у виджета погоды.
AccuweatherWidget.apk (4.x.x) (AccuweatherWidget_Main.apk (4.x.x)) — ДА. Информер погоды от Samsung + виджет к нему.
AllShareCastWidget.apk (4.1.1) (AllshareMediaServer.apk (4.1.1); AllSharePlay.apk (4.1.1); AllshareService.apk (4.1.1)) — ДА. Сервис AllShare (Раздаёт установленный софт и медиа контент).
AnalogClock.apk (AnalogClockSimple.apk (4.1.1)) — ДА. Виджет аналоговых часов.
AngryGPS.apk — ?, это lbstestmode в некоторых прошивках Samsung. Открывается по коду *#*#3214789650#*#* (быстро разряжает батарею).
ApplicationsProvider.apk — НЕТ. Требуется для установки и удаления программ.
audioTuning.apk — Да. Программа понижает громкость звука через некоторое время на Samsung (абсолютно бесполезно).
Aurora.apk — ДА. Живые обои.
AxT9IME.apk — ДА. Стандартная клавиатура Samsung. Ее можно удалить при наличии сторонней клавиатуры (например SWYPE или Smart Keyboard).
BackupRestoreConfirmation.apk (4.x.x) — НЕТ. Системный компонент для визуализации подтверждения бэкапа или откат на бэкап.
BadgeProvider.apk — НЕТ. Приложение необходимо для работы SMS и E-mail. Удаление приведет к «падению» программ, отвечающих за работу электронной почты и текстовых сообщений.
BestGroupPose.apk (4.1.1) — НЕТ. Дополнительная библиотека к стоковому приложению фотоаппарата для создания групповых снимков (удаление компонента может привести к сбою в работе основного приложения).
BlueSea.apk — ДА. Живые обои «Синее море».
BluetoothAvrcp.apk — НЕТ. Приложение необходимо для поддержки профилей Bluetooth: AVRCP, HID и т.п. управление плейером с бт гарнитуры стоп-перемотка-громкость и т.д.
BluetoothOpp.apk (Bluetooth.apk (4.x.x)) — НЕТ. Данное приложение организовывает передачу файлов между устройствами. В случае удаления, вы лишаетесь возможности передавать и принимать файлы, а так же работать с Bluetooth гарнитурой.
BluetoothServices.apk (BrcmBluetoothServices.apk; BluetoothMap.apk (4.x.x)) — НЕТ. основная служба Bluetooth. Оставьте этот файл, если Вы собираетесь использовать Bluetooth. Удаление приведет к неработоспособности всех Bluetooth-приложений.
BluetoothTestMode.apk (BluetoothTest.apk (4.x.x)) — ДА. данный apk предназначен для тестирования Вашего Bluetooth, которое доступно через сервисный код *#*#197328640#*#*. Удаление возможно, однако в некоторых случаях система тестирует BT, чтобы определить длительность передачи данных. После удаления возможны проблемы при передаче файлов, затухания при воспроизведении музыки через BT гарнитуру и т.д.
BroadcomMEMSService.apk (4.x.x) — ДА. Компонент отвечающий за настройку и работу чипа Broadcom на некоторых модификациях телефона SGSIII в которых чип GPS приёмника от одноимённого производителя компонентов радиоэлектронной связи.
Browser.apk (SecBrowser.apk (4.x.x)) — ДА. стандартный браузер, приложение отвечающее за просмотр веб-страниц. Можно удалить, при наличии стороннего браузера (Opera, Firefox или др. браузеров для Android), но в некоторых случаях виляет на автоматическую настройку APN.
BuddiesНЕТw.apk (BuddiesNow.apk) — ДА. Виджет, который входит в состав оболочки TouchWiz. Если не иcпользуете, удаляйте.
Calendar.apk (SecCalendar.apk (4.x.x)) — ДА. Приложение «календарь» в некоторых прошивках.
CalendarProvider.apk (SecCalendarProvider.apk (4.x.x)) —ДА. Синхронизация календаря в телефоне с аккаунтом Google, а так же отвечает за уведомления.
CallSetting.apk — НЕТ. Базовое приложение, необходимое для изменения настроек вызовов (ожидание вызова, ответ и т.д.).
Camera.apk — НЕТ. это приложение отвечает за камеру. Удалять только если есть альтернатива.
CameraFirmware.apk — НЕТ. это сама макропрограмма (ROM) камеры. Без данной программы Camera.apk становится бесполезным.
CapabilityManagerService.apk (4.x.x) — НЕТ. Менеджер совместимости приложений, по всей видимости запускается при каждой загрузке аппарата и проверяет установленный софт на совместимость с операционной системой.
ChatON_MARKET.apk (4.1.1) —ДА. Социальный чат от Samsung.
CertInstaller.apk — НЕТ. устанавливает сертификаты для приложений. Я полагаю, без нее Вы не сможете назначать права программам и получать доступ к определенным файлам и директориям. Догадываюсь, что и с Root-ом будут проблемы. Короче говоря, не удаляйте.
ChocoEUKor.apk —ДА. Встроенный системный шрифт.
Chrome.apk (4.1.1) —ДА. Браузер Google Chrome.
ChromeBookmarksSyncAdapter.apk (4.x.x) —ДА. Синхронизация закладок встроенного браузера с сервисом Google.
ClipboardSaveService.apk (4.x.x) —ДА. Дополнительное меню с мульти буфером обмена текстовой информацией.
ClockPackage.apk — ДА. Будильник, таймер, мировое время и часы. Если не пользуетесь альтернативами, желательно оставить, т.к. работает все стабильно и запускается из одного apk.
CloudAgent.apk (4.1.1) — ДА. Сервисный компонент облачного приложения (связан с работой DropBox и облака от Samsung).
Contacts.apk — НЕТ. Отвечает за управление контактами (контакты, группы, история вызовов и т.д.). В случае удаление, Вам придется каждый раз набирать номер вручную.
ContactsProvider.apk — НЕТ. Даёт сторонним приложениям возможность доступа к Вашим контактам на устройстве.
CoolEUKor.apk — ДА. Встроенный системный шрифт.
CSC.apk — НЕТ. В случае удаления, нарушит CSC. Теоретически, может быть удалено после первой удачной загрузки, но если когда-нибудь придется сделать ХР (сброс на заводские настройки), телефон может не загрузится.
DataCreate.apk — НЕТ. Судя по всему эта утилита искуственно генерирует трафик для определения пропускной способности между устройствами передачи данных.
Days.apk — ДА. Виджет задач на день.
DeepSea.apk (4.1.1) — ДА. Живые обои «Глубокое море».
DefaultContainerService.apk — НЕТ. Распаковывает приложения для установки
DeskClock.apk — Да. Стандартное приложение «Часы» (будильник).
DialertabActivity.apk — НЕТ. Номеронабератель. Даже если все ваши контакты уже сохранены, Вы не сможете осуществить вызов без этого приложения.
DigitalClock.apk — ДА. Виджет цифровых часов.
Divx.apk — ДА. Это некая лицензионная информация к видео проигрывателю. Я не очень часто смотрю фильмы на телефоне, однако после удаления этого файла, проблем с воспроизведением не было. Если Вы удалили его, и что-то перестало работать, пожалуйста, сообщите в комментариях.
Dlna.apk — НЕТ. Сервис allshare. Может влиять на работу БТ.
DownloadProvider.apk (SecDownloadProvider.apk (4.x.x)) — НЕТ. Обеспечивает загрузку файлов вручную и из Маркета.
DownloadProviderUi.apk (SecDownloadProviderUi.apk (4.x.x)) —Да. Оболочка приложения загрузки из стокового браузера.
DrmProvider.apk — НЕТ. Вы можете его удалить. Это приведет к невозможности воспроизведения защищенных DRM файлов таких как мелодии вызовов и звуки сообщений. Думаю, что если вам не-придется воспроизводить защищенные файлы, то в принципе его можно удалить. Однако необходимо иметь ввиду, что Вы больше не сможете воспроизвести ни один защищенный DRM файл. Этот apk занимает немало памяти и всегда работает в фоне. Это один из самых «плохих» apk-шек, который не обеспечивает никакой функционал, а просто защищает от редактирования и копирования стандартные звуки Samsung. Опыт пользователей (два сообщения).
DrmUA.apk — НЕТ. см. выше.
Dropbox.apk (4.1.1) (DropboxOOBE.apk (4.1.1)) —Да. Dropbox — сервис хранения данных.
DSMForwarding.apk —Да. Оповещение о смене SIM.
DSMLawmo.apk —Да. Lawmo-это Lock and Wipe Management Object, т.е. удаленное блокирование устройства и стирание информации через Samsung Dive.
DualClock.apk —Да. Виджет «Двойные часы». Если не используете, смело удаляйте.
EdmVpnServices.apk —Да. Судя по названию прослеживается явная пренадлежность к VPN сервису.
Email.apk — ДА. Почтовый клиент POP/IMAP. Если не нужен, удаляйте. На работу Gmail не влияет.
EmailWidget.apk — ДА. Виджет почты.
Encrypt.apk — ДА. Шифрование карты памяти (устройства) чтобы не читалась на другом устройстве.
EnhancedGoogleSearchProvider.apk — ДА. Дает возможность вызвать окно поиска по зажатию кнопки «Меню». Обычно не удаляю.
Exchange.apk (4.x.x) — ДА. Клиент MS Exchange. Если используется корпоративная почта и планировщик — то удалять нельзя.
FaceLock.apk (4.x.x) — ДА. Функция определения Вашего лица для блокировщика экрана.
FactoryTest.apk — ДА. Тест телефона (*#0*#). Можно смело удалять. Если Вы хоть раз запускали autostarts, Вы поймете сколько ресурсов отбирает этот apk во время некоторых действий. После удаления аппарат не реагирует на любой сервис код. Внимание! Были случаи когда после удаления данного файла некорректно работало приложение Радио.
FMRadio.apk — ДА. Проигрыватель FM радио.
fotaclient.apk — ДА. Обновление по воздуху.
FTC.apk — ДА. Управляет работой wi-fi для подключения к сети.
FTM.apk (FTS.apk) — ДА. Sharing Manager — Если не собираетесь использовать телефон как точку доступа или модем, то можно удалить.
Gallery3D.apk — ДА. При его удалении удаляется сама галерея и возможность в проводнике в меню «открыть с помощью» использовать стандартный видеоплеер. Заметно расходует батарею. В случае удаления, Вы не сможете быстро получить доступ к фотографиям при отсутствии альтернативы. Для ее замены я бы порекомендовал QuickPic, она справляется со своей задачей, работает быстрее и не отбирает столько памяти (однако не такая красивая как Gallery 3D). После удаления возможны проблемы с установкой стандартных обоев на экран блокировки и рабочий стол.
GameHub.apk — ДА.
Geniewidget.apk — ДА. Виджет — погода и новости, удаляется без последствий.
GlobalSearch.apk — ДА. Это поисковой сервис телефона. Через него работает EnhancedGoogleSearchProvider.
Gmail.apk — ДА. Может быть удален если не пользуетесь почтой Google, однако удаление, как правило, повлечет за собой нарушение приложения Talk.apk. Может быть повторно установлен из Маркета.
GmailProvider.apk — ДА. см. Gmail.
GmsCore.apk –– ДА. Сервисы Google Play.
GoogleApps.apk —НЕТ. Базовый файл приложений Google Необходим для Android Market.
GoogleBackupTransport.apk —ДА. Сохранение настроек и всего остального на серверах Гугл. Этим же пользуются некоторые приложения (бекап и ресторе).
GoogleCalendarSyncAdapter.apk —ДА. Синхронизация календаря с Google аккаунтом. Можно удалить, если нет необходимости в синхронизации календаря.
GoogleContactsSyncAdapter.apk —ДА. Синхронизация контактов с Google аккаунтом. Очень полезная функция. Можно удалить, если нет необходимости в синхронизации контактов.
GoogleCheckin.apk — НЕТ. Market Checking Service.
GoogleFeedback.apk —ДА. Cервис обратной связи с пользователями — удаление возможно, если используется сторонние приложения или данный функционал не нужен.
GoogleLoginService.apk (4.x.x) — НЕТ. Параметры синхронизации, необходимое приложение. Данное приложение отвечает не только за синхронизацию контактов и календаря, но и всего остального, связанного с учетной записью Google. Даже если Вы ничего не синхронизируете, не стоит его удалять.
GooglePartnerSetup.apk — ДА. Гугловская социальная приблуда.
GoogleQuickSearchBox.apk (GoogleSearch.apk) — ДА. Виджет поиска Google.
GoogleServicesFramework.apk — НЕТ. Обеспечивает работу служб Google.
GoogleSettingsProvider.apk — НЕТ. Настройки Google.
GoogleSubscribedFeedsProvider.apk — НЕТ. Необходим для Android Market. Возможно синхронизация обновлений.
GpsSetup2.apk — НЕТ. Отвечает за настройки GPS.
gtalkservice.apk — НЕТ. Удаление повлечет за собой неработоспособность Маркета. Удалять можно GTalk.
GoogleTTS.apk (4.x.x) — ДА. Голосовой движок от Google.
HelvNeueLT.apk — ДА. Системный шрифт.
HTMLViewer.apk — ДА. Отвечает за просмотр html-файлов и справок для некоторых приложений. Удаление может привести к неработоспособности Opera Mini.
HwCodec.apk — ?. Кодеки для воспроизведения?
InfoAlarm.apk — ДА. Ежедневный брифинг виджет. Если не нужен, удаляйте.
InputEventApp.apk — НЕТ.
JobManager.apk — НЕТ. Диспетчер задач.
KeyChain.apk (4.x.x) — НЕТ. Судя вот по всему это демон, связан с работой сертификатов и ключей безопасности.
Kies.apk (KiesAir.apk; kieswifi.apk) — ДА.
Kobo.apk — ДА. Журналы.
Layar-samsung.apk — ДА. Браузер дополненной реальности Layar. Выглядит впечатляюще в обзорах, но ни разу не пользовался в реальности.
LbsTestMode.apk — ДА. Режим тестирования GPS. Запускается через коду *#*#197328640#*#*.
lcdtest.apk — ДА. Удаление приведет к тому, что дисплей перестанет отключаться во время блокировки. Это можно исправить путем установки отдельных частей, но лучше оставить и забыть про него.
LGSetupWizard.apk — НЕТ. Автоматическая настройка интернета, ммс и т.д. в LG.
LiveWallpapers.apk — ДА. Живые обои.
LiveWallpapersPicker.apk — ДА. Выбор живых обоин.
LogsProvider.apk — НЕТ. Многие программы перестанут отвечать на запросы и начнут принудительно закрываться.
LunarService.apk — НЕТ. Отвечает за настройки APN мобильной сети. В случае удаления процесс GTALK_ASYNC_CONN_com.google.android.gsf.gtalkservice.AndroidEndpoint будет будить систему и увеличится «жор» батарею.
MagicSmokeWallpapers.apk — ДА. Живые обои «Дым».
Maps.apk (GMS_Maps.apk (4.x.x)) — ДА. apk файл Карт Google. Если не используете, можно удалять. Хотя довольно полезная штука, потому что поддерживается GPS.
MarketUpdater.apk — ДА. Автоматическое обновление самого Маркета. Если не нужно, можно удалить.
MediaProvider.apk — НЕТ. Необходим для получения доступа к медиа файлам и рингтонам.
MediaUploader.apk — ДА. Отвечает за загрузку изображений в picassa (или facebook как правило). Можно удалять, если не нужно.
Memo.apk — ДА. После удаления не сможете создавать заметки.
MiniDiary.apk — ДА. Мини заметки.
minimode-res.apk (4.x.x) — НЕТ. Один из компонентов пакета «миниприложения» (MiniApps).
Mms.apk — ДА. Сервис sms и mms. Можно заменить на альтернативный. Однако некоторые альтернативные приложения, например Pansi, не умеет без mms.apk получать ммс сообщения, но смс принимает. А вот HandcetSMS делает это без проблем при удалённом mms.apk.
MobilePrint.apk — ДА. Удалённая печать документов.
MobileTrackerEngineTwo.apk — ДА. Это приложение позволяет включить слежку за перемещением телефона. Данная функция призвана помочь вернуть телефон в случае кражи. Сервис постоянно висит в памяти и хорошо расходует батарею.
MobileTrackerUI.apk — ДА. См. выше.
MotionsSettings.apk — ДА. Относится к меню настроек, пункт меню «Движения».
MtpApplication.apk — ДА. При отсутствии данного приложения телефон не соединяется с компьютером в качестве накопителя.
MusicFX.apk (4.x.x) — ДА. Управление DSP процессором обработки звука.
MusicPlayer.apk — ДА. Это музыкальный проигрыватель. Может быть заменен на другой, более функциональный. Я даже советовал бы Вам его удалить, т.к. при использовании нескольких аудио проигрывателей, возможна нестабильная работа обоих, а так же одновременно воспроизведение разных композиций по BT. При удалении на HTC возможны проблемы с выбор мелодии на звонок будильника.
MyFiles.apk — ДА. Стандартный браузер фалов от Samsung. Может быть заменен на более функциональный, однако для повседневного использования он годится.
NetworkLocation.apk — ДА. Полу-точная симуляция GPS. Программа использует ячейку (сектор на БС), на которой находится телефон для определения местонахождения без задействования GPS приемника, тем самым экономя расход батареи. В случае удаления, потребуется вводить информацию о своем местоположении вручную в таких программах как прогноза погоды и т.п., или же включать GPS приемник.
oem_install_flash_player.apk — ДА. Флеш плеер, если не юзаем, то удаляем.
OtaProvisioningService.apk — ДА. Это приложение можно удалять, если не используете «обновление по воздуху». На телефонах Samsung может применяться для обновления программ из SamsungAppStore. На HTC лучше не удалять, т.к. производитель практикует обновление ПО данным способом.
PackageInstaller.apk — НЕТ. Обеспечивает установку приложений.
PanningTryActually.apk — НЕТ. Паннинг для камеры фото/видео.
PCSync.apk — Да. Приложение от производителя для синхронизация с ББ в некоторых устройствах.
PCWClientS.apk — НЕТ. Остановка выяснения причин аварии системных процессов.
Personalization.apk — НЕТ. Персонализация настроек.
Phone.apk — НЕТ. Приложение, отвечающее за телефонную часть. После удаления, не можете набирать номер, просматривать вызовы и т.д.
Phone_Util.apk — НЕТ.
PhoneCrashNotifier.apk — НЕТ.
PhoneErrService.apk — НЕТ.
Phonesky.apk (4.x.x) — Да. Google Play Market. На некоторых устройствах его можно удалять из системы, так как он находится ещё и в папке data/app и нормально работает. Но следует учесть, что при его удалении из системной папки после ХР маркета на устройстве не будет.
PicoTts.apk — ДА. Это часть программы для перевода текста в речь (не речь в текст). Приложение для людей, лишенных зрения. Также является частью Google GPS, которая может диктовать «поверните направо» или «налево». На работоспособность навигации не влияет. После удаления желательно так же избавиться от TtsService.apk. При удалении необходимо отключить «Режим вождения» в настройках.
PlusOne.apk (4.x.x) — ДА. Социальный сервис от Google.
Preconfig.apk — НЕТ. Самсунговский модуль изменения кода CSC страны.
PressReader.apk — ДА. Читалка новостей.
Protips.apk — ДА. Виджет «помощь в использ. андроида»
ReadersHub.apk (4.x.x) — ДА.
RoseEUKor.apk (4.x.x) — ДА. Системный шрифт.
SamsungApps.apk — ДА. Приложение Samsung apps. Если будете удалять, можно как правило удалять signin.apk. Удаление может повлиять на синхронизацию музыки через Kies, однако обновить прошивку Вы сможете. После удаления, виджеты Samsung и touchwiz остаются работоспособными.
SamsungAppsUNAService.apk — Да, в случае удаления SamsungApps.
Samsungservice.apk — ДА. Синхронизация с сервисом Самсунга.
SamsungTTS.apk (4.x.x) —ДА. Голосовой движок от Samsung.
SamsungWidget_CalendarClock.apk — ДА. Виджет Calendar clock.
SamsungWidget_FeedAndUpdate.apk — ДА. Виджет Feeds and Updates.
SamsungWidget_StockClock.apk — ДА. Еще один виджет Stock clock.
SamsungWidget_WeatherClock.apk — ДА. Виджет Weather clock.
ScreenCaptureService.apk (ScreenCapture.apk) — Да. Приложение для съемки скриншотов.
SecurityProvider.apk — НЕТ. Шифрование соединения.
SelfTestMode.apk — ДА. Самодиагностика аппарата при загрузке.
SerialNumberLabelIndicator.apk — НЕТ. Похоже связано с определением IMEI.
serviceModeApp.apk — НЕТ. Приложение необходимо для обработки сервис-кодов и задач.
Settings.apk — НЕТ. Меню настроек телефона.
SettingsProvider.apk — НЕТ. Осуществляет прием и применение настроек, полученных в текстовом или сервисном сообщении. Лучше оставить, т.к. некоторые писали о «падении» программ после удаления.
SetupWizard.apk — ДА. Теоретически, может быть удалено после первой удачной загрузки, но могут возникнуть трудности после ХР.
shutdown.apk — НЕТ. Информирует о разрядке батареи.
signin.apk — ДА. Учётная запись Samsung. Необходимо для отслеживания координат устройства.
SisoDrmProvider.apk — НЕТ. Необходим для работы DRM. Если Вы обходитесь без DRMUA и DRMService, возможно этот файл можно удалить. Я так и не смог победить его в своем телефоне.
SnsAccount.apk — ДА. Синхронизирует записи из facebook и twitter.
SnsProvider.apk (SnsDisclaimer.apk; SnsImageCache.apk) — ДА. См. выше.
SocialHub.apk (SocialHubWidget.apk) —ДА. Социальные сети.
SoundPlayer.apk — ДА. Не путайте с MusicPlayer.apk. Данное приложение воспроизводит звуки и рингтоны. Он может быть удален, но у вас появятся небольшие ограничения: так как он работает немного быстрее и больше подходит по назначению, чем MusicPlayer или сторонний проигрыватель. Советую оставить.
SpeechRecorder.apk — НЕТ. Записывает образцы речи для тестирования ее распознавания. Голосовое управление им пользуется.
Stk.apk — НЕТ. Приложение для отображения меню оператора, которое обычно предлагает гороскопы, новости, анекдоты, музыку и т.д. за деньги. Если не нужно, удаляйте. При отключении в той же сессии перезапускаются все sim карты, gprs может не работать пока не перезагрузить аппарат, после чего все снова работает. Желательно оставить, т.к. после ХР могут возникать проблемы с автонастройкой APN и ММS.
Street.apk — ДА. Просмотр улиц для Google Maps. Удаление не отразится на работе Google Maps, Вы просто не сможете посмотреть фотографии улиц.
Swype.apk — ДА. Клавиатура Swype, превосходная альтернатива клавиатуре Samsung. Хорошо выполняет свою задачу, предугадывает текст, но не интуитивно понятна для новичков.
syncmldm.apk — ДА. Обновление программы аппарата.
syncmlds.apk — ДА. Настройки синхронизации, которые доступны из меню. Если они Вам не нужны, можете удалять.
SystemUI.apk — НЕТ. Android user interface — Пользовательский интерфес (все связанное с формированием рабочего стола, шторки и статус бара и т.д.).
Talk.apk — ДА. Google Talk. Возникали некоторые споры относительно зависимостей данного приложения. Речь шла о том, что при удалении Google Talk переставал работать Gmail или Market, многие говорили, что это не так. Так что тут будьте внимательнее.
talkback.apk — ДА. Специальные возможности для людей с ограниченными способностями.
TalkProvider.apk — ДА. См. выше.
TelephonyProvider.apk — НЕТ. Используется для хранения смс, контактов и вызовов.
thinkdroid.apk — ДА. Программа для работы с документами microsoft office. Удаление приведет к утрате возможности открывать файлы .doc, .xls и .pps.
TouchWiz30Launcher.apk (SecLauncher2.apk (4.x.x)) — НЕТ. Даже если вы используете стороннее рабочее окружение, например, Zeam или LauncherPro, удаление TouchWiz крайне не рекомендуется. В случае ХР Вы можете потерять работоспособность телефона.
TouchWizCalculator.apk — ДА. Приложение Calculator, хорошее и функциональное приложение, хотя есть альтернативы.
TouchWizCalendar.apk — ДА. Календарь.
TouchWizCalendarProvider.apk — НЕТ. Обеспечивает синхронизацию приложения Календарь с временем, датой и настройками телефона.
TtsService.apk — ДА. См. PicoTts.apk
TwWallpaperChooser.apk — ДА. Позволяет выбирать обои. Если у Вас есть стандартная галерея или QuickPic, Вы можете устанавливать обои через них. Однако Вы не сможете выбрать те обои, которые находятся внутри данного apk.
UNAService.apk — ДА. Приложение Samsung Social Hub.
UserDictionaryProvider.apk — НЕТ. Пользовательский словарь для предугадывания слов при наборе. Сюда добавляются все неизвестные ранее слова, имена, ники и т.д. Теоретически удалить можно в случае, если стандартная клавиатура не нужна. Без данной программы стандартная клавиатура Android не работает, а так же возможны общие сбои!
Vending.apk — НЕТ. Часть Android Market. Фактически это и есть Маркет.
VideoEditor.apk — ДА. Редактор видео.
VideoPlayer.apk — ДА. Видео проигрыватель. На Ваше усмотрение.
VoiceDialer.apk — ДА. Позволяет осуществлять быстрый набор голосом. Вы диктуете имя, и телефон сам набирает номер. Это получается не всегда и только при включенном интернете. Насколько я понял, программа отправляет запрос на сервер Google обработанный голосовой запрос, и Google возвращает назад уже готовое слово. Удаляйте, если не пользуетесь.
VoiceRecorder.apk — ДА. Позволяет записывать голос. Хотя качество и не очень, для голосовых заметок его вполне достаточно.
VoiceSearch.apk — —Да. Голосовой поиск Google.
VpnServices.apk — ДА. VPN для Android. Если не нужно, можно удалять.
WapService.apk — ? Отвечает за работу WAP(?)
wipereceiver.apk — ДА. Припоминаете mobile tracker? Это приложение для того, чтобы стереть информацию с телефона удаленно, в случае его кражи.
WlanTest.apk — ДА. Тестирование настроек беспроводного доступа, доступно через то самое тестовое меню. Необходим для обновлений OTA.
WriteandGo.apk — ДА. Приложение Write and Go на телефонах Samsung.
wssomacp.apk — НЕТ. Необходимо для работы SMS.
wssyncmlnps.apk — ДА. Over The Air Programming. Это необходимо для того, чтобы Ваш провайдер мог при необходимости присылать Вам или изменять настройки через сервисные сообщения. (у нас не используется). Можно удалять. Вариант 2: Синхронизация с Samsung Kies.
YouTube.apk — ДА. Т.к. у платформы есть ограничения на воспроизведение Flash, это приложение позволяет Вам получить полный доступ к youtube, вместо того, чтобы пользоваться им через браузер. Можно удалить, если Вы не смотрите ролики онлайн.
Zinio.apk — ДА. Интернет-журналы.

За основу был взят перевод этого топика.
Для дополнения списка взята информация отсюда.

Зелёным выделены приложения, которые можно удалять;
Красным выделены приложения, которые нельзя/нежелательно удалять.

Apollo.apk — Стандартный музыкальный плеер, можно заменить на альтернативный.
ApplicationsProvider.apk — Позволяет получить список установленных в аппарате приложений и необходимо для установки файлов apk.
BackupRestoreConfirmation.apk — Резервное копирование.
Bluetooth.apk — Приложение для работы с Bluetooth.
Browser.apk — Стоковый браузер, можно заменить на другой.
Calculator.apk — Калькулятор.
Calendar.apk — Календарь.
CalendarProvider.apk — Синхронизация календаря.
Camera.apk — Приложение, отвечающее за камеру.
CertInstaller.apk — Установка сертификатов.
CMWallpapers.apk — Обои.
Contacts.apk — Контакты.
ContactsProvider.apk — Синхронизация контактов.
DefaultContainerService.apk — Необходимо для установки приложений.
DeskClock.apk — Часы и будильник.
Development.apk — Приложение Dev Tools.
DownloadProvider.apk — Загрузка приложений и файлов из маркета, браузера.
DownloadProviderUi.apk — Приложение «Загрузки».
DrmProvider.apk — DRM функции для доступа к медиафайлам.
DSPManager.apk — Эквалайзер.
Email.apk — Приложение Email.
Exchange.apk — Синхронизация.
Galaxy4.apk — Обои.
Gallery2.apk — Стоковая галерея. Можно удалить при наличии альтернативы.
HoloSpiralWallpaper.apk — Обои.
HTMLViewer.apk — Необходимо для просмотра HTML.
KeyChain.apk — Хранение паролей.
LatinIME.apk — Стандартная клавиатура.
LiveWallpapers.apk — Обои.
LiveWallpapersPicker.apk — Приложение, позволяющее выбирать живые обои.
MagicSmokeWallpapers.apk — Обои.
MediaProvider.apk — Необходима для доступа к медиафайлам.
Mms.apk — Приложение SMS/MMS. Можно удалять, но лучше оставить.
NoiseField.apk — Обои.
P1Parts.apk — Расширенные настройки.
PackageInstaller.apk — Необходимо для установки приложений.
PhaseBeam.apk — Обои.
Phone.apk — Приложение Телефон.
PicoTts.apk — Преобразование текста в речь.
Provision.apk — Необходимо для первого запуска. На некоторых устройствах после удаления возможны проблемы с экраном блокировки.
QuickSearchBox.apk — Виджет поиска.
RomManager.apk — ROM Manager.
SamsungServiceMode.apk — ?
Settings.apk — Настройки.
SettingsProvider.apk — Хранилище настроек.
SharedStorageBackup.apk — ?
SoundRecorder.apk — Диктофон.
SpareParts.apk — Меню дополнительных настроек.
Stk.apk — Меню SIM-карты, но лучше оставить.
Superuser.apk — При желании можно заменить на приложение ® SuperSU
SystemUI.apk — Графический интерфейс.
TelephonyProvider.apk — Настройки мобильной сети.
Term.apk — Эмулятор терминала.
ThemeChooser.apk — Необходимо для поддержки тем.
ThemeManager.apk — Необходимо для поддержки тем.
Trebuchet.apk — Стандартный лаунчер, можно заменить (например на Apex Launcher).
UserDictionaryProvider.apk — Словари для стоковой клавиатуры.
VideoEditor.apk — Редактор видео.
VisualizationWallpapers.apk — Живые обои.
VoiceDialer.apk — Голосовой набор.
VpnDialogs.apk — Приложение для VPN.
WAPPushManager.apk — Отвечает за работу WAP.

Полный список приложений с описанием и указанием последствий после удаления для CyanogenMod 10.2 и CyanogenMod 11 .

Список приложений для прошивок, основанных на CyanogenMod 13 (на англ. языке)

andro >

Так что я пытаюсь сделать, в основном, когда/когда пользователь вводит текст в EditText, я в основном хочу искать все слова, которые начинаются с того, что находится внутри EditText (достигается путем редактирования editText.getText(). ToString ( )). Я добавил TextChangedListener в свой EditText и всякий раз, когда пользователь вводит какой-либо символ, он вызывает метод, называемый addResults, который использует следующий код:

И нет ничего плохого в этом методе, он действительно получает правильные слова и все, но проблема заключается в том, что если пользователь вводит WHILE, пытаясь получить слова, он, похоже, не обновляется (по-прежнему отображаются результаты из старого поиска). Внутри моего обработчика я просто устанавливаю адаптер моего ListView в массив строк (resultsArray), полученный из метода). И некоторые возможные решения, о которых я могу думать, это либо немедленно остановить выполнение потока, либо найти способ заставить его отменить предыдущий запрос, если пользователь печатает, когда поток запущен, и заставить обработать текущий текст внутри EditText. Будем очень благодарны за любые другие решения. Благодарю.

Примечание. Он отлично работает, если поток завершает выполнение до того, как пользователь наберет. Это становится проблемой, когда поток все еще выполняется, и пользователь начинает печатать.

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих