Передача sysui андроид что это
Перейти к содержимому

Передача sysui андроид что это

  • автор:

Как включить меню настроек интерфейс System UI Tuner в Android 6.0 и старше (Добавлено: инструкция для Android 9, Android 10, Android 11 и 12)

Как включить меню настроек интерфейса System UI Tuner в Android 6.0 Marsmallow

Оригинал статьи от 10.07.2015: Сегодня речь пойдет о System UI Tuner или скрытом разделе меню настроек системы, с помощью которого можно менять содержимое панели быстрых настроек, управлять уведомлениями от приложений в строке состояния и возможностью включения индикации заряда батареи смартфона или планшета в процентах.

Располагается этот раздел в самом конце основного меню настроек планшета или смартфона, но по умолчанию его отображение в Android 6.0 Marsmallow и выше отключено.

Как включить меню настроек интерфейса System UI Tuner в Android 6.0 Marsmallow

Как же включить отображение раздела System UI Tuner в меню настроек?

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

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

Вот как это всё выглядит в реальности:

Выключить System UI Tuner можно, как видно на видео выше, из его же окна, нажав на кнопку меню в виде вертикального троеточия, либо таким же методом, каким мы его включали: длинным тапом по кнопке с изображением шестеренки в меню быстрых настроек системы.

Добавлено 11.08.2018, обновлено 20.07.2019, 02.08.2021:

Те, кто имеет смартфон с операционной системой Android 9.0 Pie и старше заметили, что включить System UI Tuner в меню настроек путем нажатия на значок в виде шестеренки, у них не получается.

Неужели разработчики в конце концов решили убрать его?

Переживать не стоит: System UI Tuner в Android 9.0 и в более поздних версиях этой системы, вплоть до Android 12 по-прежнему имеется, и сегодня мы расскажем вам как до него добраться

Как запустить System UI Tuner в Android 9.0 — Android 12

Для того, чтобы открыть System UI Tuner в Android 9 или Android 10 вам понадобится лончер Nova Launcher или любой другой, который имеет доступ к настройкам системы и, в частности, действиям приложений.

Таких лончеров имеется множество, но не всегда они совместимы с последними версиями Android , поэтому мы расскажем вам как запустить System UI Tuner на примере Nova Launcher:

1. Скачайте с этой страницы Google Play приложение Nova Launcher и запустите его

2. Нажмите на свободном месте рабочего стола и удерживайте палец, пока не появится меню настроек и установки обоев и виджетов

Как запустить System UI Tuner в Android 9.0 Pie

3. Выберите «Виджеты», а затем в открывшемся окне: «Nova Launcher» -> «Действия приложений» (В более свежих версиях «Nova Launcher» -> «Активити»)

Как запустить System UI Tuner в Android 9.0 Pie

4. В открывшемся перечне найдите «Интерфейс системы», откройте их и опуститесь вниз к пункту: «Интерфейс системы: Демо режим»

Как запустить System UI Tuner в Android 9.0 Pie

5. Нажмите на «Интерфейс системы: Демо режим» и не отпуская палец перетащите его на рабочий стол. Если система сообщит вам о том, что у Nova Launcher нет прав для создания виджетов, предоставьте их.

Как запустить System UI Tuner в Android 9.0 Pie

6. Всё, теперь кликнув по новому, созданному вами виджету вы откроете System UI Tuner, который в Android 9.0 позволяет управлять отображением значков в панели уведомлений, включать и выключать отображение процентов зарядки батареи и включать отображение времени с секундами:

Как запустить System UI Tuner в Android 9.0 Pie

А вот так выглядит System UI Tuner в операционной системе Android 10:

Похожие материалы:

передача SysUI

Забудь о существовании этой штуковины, она тебе не нужна. Называется так потому что в Google работают надмозги и Dump SysUI Heap перевели как «Передача SysUI».

Это опция для разработчиков SystemUI – системной оболочки Android: навбар, статусбар, вот это всё.

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

a1batross ★★★★★
( 03.10.20 23:02:48 MSK )
Последнее исправление: a1batross 03.10.20 23:03:12 MSK (всего исправлений: 1)

Ответ на: комментарий от a1batross 03.10.20 23:02:48 MSK

надмозги и Dump SysUI Heap перевели как «Передача SysUI».

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

Как работает SystemUI в Android

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

В системе Android, SystemUI — это приложение, путь к исходному коду которого находится в platform_frameworks_base/packages/SystemUI/, на девайсе оно находится в system/priv-app/-SystemUI.

priv-app — это каталог, где хранятся привилегированные приложения. К слову, по пути system/app лежат предустановленные приложения, а обычные приложения, которые мы устанавливаем на свой девайс самостоятельно, хранятся в data/app.

Тут сразу возникает вопрос: почему нельзя засунуть все предустановленные и привилегированные приложения в один каталог, зачем нужно это разделение?

Дело в том, что некоторые приложения более системные, чем другие:) И это разделение необходимо для того чтобы уменьшить покрытие эксплойтами системных приложений, для получения доступа к защищенным операциям. Можно создавать приложение, которое будет иметь специальный ApplicationInfo.FLAG_SYSTEM и в системе получит больше прав, однако apk файл с таким разрешением будет помещен в раздел system.

Итак, SystemUI — это apk-файл, который по сути своей обычное приложение. Однако, если посмотреть на сложное устройство SystemUI, перестает казаться, что это всего лишь простое приложение, верно?

Данное приложение выполняет весьма важные функции:
  • Навигация
  • Недавние приложения
  • Быстрые настройки
  • Панель уведомлений
  • Экран блокировки
  • Регулятор громкости
  • Главный экран
  • .

Запуск SystemUI

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

Если мы залезем в SystemServer, который является одним из двух столпов в мире Android (второй — Zygote, но об этом я расскажу как-нибудь в другой раз), то мы можешь найти место, где стартует SystemUI при загрузке системы.

 static final void startSystemUi(Context context, WindowManagerService windowManager) < Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); //Slog.d(TAG, "Starting service: " + intent); context.startServiceAsUser(intent, UserHandle.SYSTEM); windowManager.onSystemUiStarted(); >

Тут мы видим как запускается сервис SystemUI с помощью непубличного API startServiceAsUser. Если бы вы захотели использовать это, то вам пришлось бы обратиться к рефлексии. Но если вы решите использовать reflection API в Android — подумайте несколько раз, стоит ли это того. Подумайте раз сто:)

Итак, тут создается отдельный процесс для приложения и по факту каждый раздел SystemUI является отдельным сервисом или независимым модулем.

public abstract class SystemUI implements SysUiServiceProvider < public Context mContext; public Map, Object> mComponents; public abstract void start(); protected void onConfigurationChanged(Configuration newConfig) < >public void dump(FileDescriptor fd, PrintWriter pw, String[] args) < >protected void onBootCompleted() < >@SuppressWarnings("unchecked") public T getComponent(Class interfaceType) < return (T) (mComponents != null ? mComponents.get(interfaceType) : null); >public void putComponent(Class interfaceType, C component) < if (mComponents != null) < mComponents.put(interfaceType, component); >> public static void overrideNotificationAppName(Context context, Notification.Builder n, boolean system) < final Bundle extras = new Bundle(); String appName = system ? context.getString(com.android.internal.R.string.notification_app_name_system) : context.getString(com.android.internal.R.string.notification_app_name_settings); extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, appName); n.addExtras(extras); >> 

Метод start() вызывается для запуска каждой службы, которые перечислены ниже.

 com.android.systemui.Dependency com.android.systemui.util.NotificationChannels com.android.systemui.statusbar.CommandQueue$CommandQueueStart com.android.systemui.keyguard.KeyguardViewMediator com.android.systemui.recents.Recents com.android.systemui.volume.VolumeUI com.android.systemui.stackdivider.Divider com.android.systemui.SystemBars com.android.systemui.usb.StorageNotification com.android.systemui.power.PowerUI com.android.systemui.media.RingtonePlayer com.android.systemui.keyboard.KeyboardUI com.android.systemui.pip.PipUI com.android.systemui.shortcut.ShortcutKeyDispatcher @string/config_systemUIVendorServiceComponent com.android.systemui.util.leak.GarbageMonitor$Service com.android.systemui.LatencyTester com.android.systemui.globalactions.GlobalActionsComponent com.android.systemui.ScreenDecorations com.android.systemui.fingerprint.FingerprintDialogImpl com.android.systemui.SliceBroadcastRelayHandler 

Регулирование громкости

Мы регулярно пользуемся кнопками громкости на своих устройствах, но не задумываемся какие процессы должны произойти в системе для того чтобы мы могли прибавить или убавить звук. Операция кажется довольно простой на словах, но если заглянуть в VolumeUI, который находится в подпапке SystenUI/volume, в разных режимах интерфейс имеет свою вариацию.

Я уже говорила о том, что сервисы SystemUI запускаются методом start(). Если мы посмотрим на класс VolumeUI, то он тоже наследуется от SystemUI.

public class VolumeUI extends SystemUI < private static final String TAG = "VolumeUI"; private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG); private final Handler mHandler = new Handler(); private boolean mEnabled; private VolumeDialogComponent mVolumeComponent; @Override public void start() < boolean enableVolumeUi = mContext.getResources().getBoolean(R.bool.enable_volume_ui); boolean enableSafetyWarning = mContext.getResources().getBoolean(R.bool.enable_safety_warning); mEnabled = enableVolumeUi || enableSafetyWarning; if (!mEnabled) return; mVolumeComponent = new VolumeDialogComponent(this, mContext, null); mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning); putComponent(VolumeComponent.class, getVolumeComponent()); setDefaultVolumeController(); >…

Тут мы видим что с помощью mEnabled мы определяем, следует ли нам показывать панель с настройкой звука. И судя по VolumeDialogComponent, VolumeUI отображает звуковую панель в виде диалога. Но все действия относительно нажатия на клавиши громкости обрабатываются в PhoneWindow.

 protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) < . switch (keyCode) < case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_MUTE: < // If we have a session send it the volume command, otherwise // use the suggested stream. if (mMediaController != null) < mMediaController.dispatchVolumeButtonEventAsSystemService(event); >else < getMediaSessionManager().dispatchVolumeKeyEventAsSystemService(event, mVolumeControlStreamType); >return true; > . protected boolean onKeyUp(int featureId, int keyCode, KeyEvent event) < final KeyEvent.DispatcherState dispatcher = mDecor != null ? mDecor.getKeyDispatcherState() : null; if (dispatcher != null) < dispatcher.handleUpEvent(event); >//Log.i(TAG, "Key up: repeat=" + event.getRepeatCount() // + " flags=0x" + Integer.toHexString(event.getFlags())); switch (keyCode) < case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: < // If we have a session send it the volume command, otherwise // use the suggested stream. if (mMediaController != null) < mMediaController.dispatchVolumeButtonEventAsSystemService(event); >else < getMediaSessionManager().dispatchVolumeKeyEventAsSystemService( event, mVolumeControlStreamType); >return true; > …

Насколько мы видим, KEYCODE_VOLUME_UP (+) не обрабатывается и перейдет в обработку KEYCODE_VOLUME_DOWN (-). И в обоих событиях, как в onKeyDown, так и в onKeyUp вызывается метод dispatchVolumeButtonEventAsSystemService.

 public void dispatchVolumeButtonEventAsSystemService(@NonNull KeyEvent keyEvent)

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

В итоге когда мы доберемся до AudioService, где будет вызван sendVolumeUpdate, где помимо вызова метода postVolumeChanged, будет установлен интерфейс HDMI.

 // UI update and Broadcast Intent protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) < . mVolumeController.postVolumeChanged(streamType, flags); >private int updateFlagsForSystemAudio(int flags) < . if (mHdmiSystemAudioSupported && ((flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0)) < flags &= ~AudioManager.FLAG_SHOW_UI; >. > return flags; > public void postVolumeChanged(int streamType, int flags)

RingtonePlayer

RingtonePlayer в Android выполняет роль проигрывателя. Он так же наследуется от SystemUI и в методе start() мы видим:

 @Override public void start()

Здесь у нас устанавливается mCallback, который по сути является экземпляром IRingtonePlayer.

private IRingtonePlayer mCallback = new IRingtonePlayer.Stub() < @Override public void play(IBinder token, Uri uri, AudioAttributes aa, float volume, boolean looping) throws RemoteException < . >@Override public void stop(IBinder token) < . >@Override public boolean isPlaying(IBinder token) < . >@Override public void setPlaybackProperties(IBinder token, float volume, boolean looping) < . >@Override public void playAsync(Uri uri, UserHandle user, boolean looping, AudioAttributes aa) < . >@Override public void stopAsync() < . >@Override public String getTitle(Uri uri) < . >@Override public ParcelFileDescriptor openRingtone(Uri uri) < . >>;

В итоге можно управлять RingtonePlayerService с помощью Binder для воспроизведения звуковых файлов.

PowerUI

PowerUI отвечает за управление питанием и уведомлениями. Аналогично наследуется от SystemUI и имеет метод start().

public void start() < mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mHardwarePropertiesManager = (HardwarePropertiesManager) mContext.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE); mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime(); mWarnings = Dependency.get(WarningsUI.class); mEnhancedEstimates = Dependency.get(EnhancedEstimates.class); mLastConfiguration.setTo(mContext.getResources().getConfiguration()); ContentObserver obs = new ContentObserver(mHandler) < @Override public void onChange(boolean selfChange) < updateBatteryWarningLevels(); >>; final ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), false, obs, UserHandle.USER_ALL); updateBatteryWarningLevels(); mReceiver.init(); showThermalShutdownDialog(); initTemperatureWarning(); >

Как мы видим из приведенного выше кода, происодит подписка на изменения Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, а после — вызов mReceiver.init().

 public void init() < // Register for Intent broadcasts for. IntentFilter filter = new IntentFilter(); filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiver(this, filter, null, mHandler); >

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

Задачи

Recents — это основная и часто используемая функция в мобильных устройствах на базе Android.

Главные функции:
  • Отображение всех задач
  • Переключение между задачами
  • Удаление задач

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

А в с помощью RecentTaskInfo мы можем получить информацию о конкретной задаче.

public static class RecentTaskInfo implements Parcelable < public int id; public int persistentId; public Intent baseIntent; public ComponentName origActivity; public ComponentName realActivity; public CharSequence description; public int stackId; . 

Вообще, запущенные задачи можно вынести в отдельную тему. Я изучила ее со всех сторон, так как хотела размывать экран приложения перед переходом приложения в background, чтобы в RecentsTask отображалась нечитаемая версия снапшота. Однако, проблема заключается в том, что снапшот приложения берется раньше, чем вызывается onPause(). Эту проблему можно решить несколькими способами. Либо выставлять флаг, чтобы система просто скрывала содержимое экрана с помощью

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);

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

Можно вообще сделать так, чтобы конкретная activity приложения не отображалось в задачах, проставив в манифесте

android:excludeFromRecents = "true"

Либо можно воспользоваться хитростью с помощью

Intent.FLAG_ACTIVITY_MULTIPLE_TASK

Можно задать основной активности выше приведенный флаг excludeFromRecents = true, для того чтобы ее экран отсутствовал в запущенных задачах, но во время загрузки приложения запустить отдельную задачу, которая будет показывать либо размытый скриншот с основной активности, либо любое другое изображение. Более подробно, как это можно сделать описано в официальной документации на примере Google Drive.

Экран блокировки

Keyguard уже посложнее всех вышеприведенных модулей. Он представляет из себя сервис, который запускается в SystemUI, а управляется при помощи KeyguardViewMediator.

private void setupLocked() < . // Assume keyguard is showing (unless it's disabled) until we know for sure, unless Keyguard // is disabled. if (mContext.getResources().getBoolean( com.android.keyguard.R.bool.config_enableKeyguardService)) < setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser()), mAodShowing, mSecondaryDisplayShowing, true /* forceCallbacks */); >else < // The system's keyguard is disabled or missing. setShowingLocked(false, mAodShowing, mSecondaryDisplayShowing, true); >. mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0); String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND); if (soundPath != null) < mLockSoundId = mLockSounds.load(soundPath, 1); >. int lockSoundDefaultAttenuation = mContext.getResources().getInteger( com.android.internal.R.integer.config_lockSoundVolumeDb); mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20); . >

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

Панель уведомлений

  1. Инициализация SystemBars
  2. Отображение уведомлений
private void createStatusBarFromConfig()

То мы видим ссылку на ресурс из которого читается имя класса и создается его экземпляр.

com.android.systemui.statusbar.phone.StatusBar

Таким образом мы видим что тут вызывается StatusBar, который будет работать с выводом уведомлений и UI.

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

P.S. Подбор материала и более короткие статьи я всегда выставляю на @paradisecurity в телеграм.

  • android
  • systemui
  • разработка по
  • мобильная разработка
  • архитектура android-приложений
  • Разработка мобильных приложений
  • Разработка под Android

Автономная работа android-приложений и алгоритмы синхронизации данных Текст научной статьи по специальности «Компьютерные и информационные науки»

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Демиш Всеволод Олегович, Пищик Борис Николаевич

Рассматриваются проблемы разработки мобильных приложений , поддерживающих автономный режим работы (без подключения к сети) с последующим проведением сеансов синхронизации связи. На примере Android приложений рассмотрены алгоритмы синхронизации данных, используемые в Google Analytics и Evernote. Обозначена актуальность задачи оптимизации хранения данных, необходимых для сеансов синхронизации, на мобильном устройстве.

i Надоели баннеры? Вы всегда можете отключить рекламу.

Похожие темы научных работ по компьютерным и информационным наукам , автор научной работы — Демиш Всеволод Олегович, Пищик Борис Николаевич

Синхронизация данных на мобильных платформах
Мобильное приложение непрерывной передачи видеоданных в облачные сервисы

Усовершенствование дискреционной модели доступа мобильных приложений к сервисам операционной системы Android

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

OFFLINE ANDROID APPLICATION AND ALGORITHMS OF DATA SYNCHRONIZATION

This article deals with problem of development mobile applications allowing offline mode (without network connection) with following synchronization sessions. By example of Android applications described algorithm of data sync used in Google Analytics and Evernote. Denoted actuality of optimization data required for synchronization sessions on mobile devices.

Текст научной работы на тему «Автономная работа android-приложений и алгоритмы синхронизации данных»

В. О. Демиш, Б. Н. Пищик

Новосибирский государственный университет ул. Пирогова, 2, Новосибирск, 630090, Россия

Конструкторско-технологический институт вычислительной техники СОРАН ул. Акад. Ржанова, 6, Новосибирск, 630090, Россия

АВТОНОМНАЯ РАБОТА ANDROID-ПРИЛОЖЕНИЙ И АЛГОРИТМЫ СИНХРОНИЗАЦИИ ДАННЫХ

Рассматриваются проблемы разработки мобильных приложений, поддерживающих автономный режим работы (без подключения к сети) с последующим проведением сеансов синхронизации связи. На примере Android приложений рассмотрены алгоритмы синхронизации данных, используемые в Google Analytics и Evernote. Обозначена актуальность задачи оптимизации хранения данных, необходимых для сеансов синхронизации, на мобильном устройстве.

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

Согласно данным CiscoSystems объем мобильного трафика за 2013 г. увеличился на 83 % -до 1,5 экзабайтов к концу 2013 г. с 820 петабайтов в конце 2012 г. 1 Темпы роста рынка мобильных устройств говорят о том, что тенденция роста объемов мобильного трафика будет только укрепляться.

С развитием мобильных устройств стремительно развивается и сфера мобильных приложений. Растет количество мобильных приложений, стремительно расширяются возможности инструментов для их разработки. К примеру, если сейчас начать обучаться программированию под мобильную операционную систему Android по литературе 2-3-годичной давности, то вполне можно встретить множество устаревших (deprecated) методов. Это объяснимо: с мая 2010 по октябрь 2013 г. Google продвинула операционную систему Android с версии 2.2 до 4.4.

Параллельное распространение технологии облачных вычислений (Cloud Computing) [1] явным образом приводит к необходимости взаимодействия мобильных устройств и облачных сервисов - ведь это взаимодействие двух стремительно развивающихся в настоящее время технологий.

С учетом того, что облачные сервисы требуют постоянного подключения к сети Интернет, а мобильные устройства зачастую работают в режиме оффлайн, перед разработчиками мобильных приложений встает задача синхронизации (или интеграции, в зависимости от за-

1 Cisco Systems. Cisco Visual Networking Index: Global Mobile. 2014. URL: http://www.cisc0.c0m/c/en/us/s0luti0ns/ collateral/service-provider/visual-networking-index-vni/white_paper_cll-520862.pdf

Демиш В. О., Пищик Б. Н. Автономная работа аш!пЛ-приложений и алгоритмы синхронизация данных // Вестн. Новосиб. гос. ун-та. Серия: Информационные технологии. 2014. Т. 12, вып. 3. С. 25-33.

ISSN 1818-7900. Вестник НГУ. Серия: Информационные технологии. 2014. Том 12, выпуск 3 © В. О. Демиш, Б. Н. Пищик, 2014

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

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

• Dropbox (http://www.dropbox.com) - облачное хранилище данных. Dropbox позволяет пользователю размещать файлы на удаленных серверах при помощи клиента или с использованием веб-интерфейса через браузер. При установке клиентского программного обеспечения Dropbox на компьютере создается синхронизируемая папка. Существуют мобильные клиенты для мобильных устройств.

• Evernote (http://evernote.com) - веб-сервис и набор программного обеспечения для создания и хранения заметок. В качестве заметки может выступать фрагмент форматированного текста, веб-страница целиком, фотография, аудиофайл или рукописная запись. Заметки могут также содержать вложения с файлами другого типа. Их можно сортировать по блокнотам, присваивать им метки, редактировать и экспортировать. Заметки со всех устройств пользователя синхронизуются с сервисом. Существуют мобильные клиенты для мобильных устройств.

• AmazonKindle (http://kindle.amazon.com) - вместе с серией электронных книг компания Amazon.com выпускает мобильные приложения, позволяющие читать книги на мобильных устройствах. При этом происходит синхронизация книг и закладок в книгах, читаемых с различных устройств.

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

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

В настоящей статье приведен анализ решения задачи отложенной синхронизации данных от Google, реализованного в сервисе сбора аналитики Google Analytics [2], а также решения от Evernote для синхронизации электронных заметок на различных устройствах.

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

Размещаемый таким образом JavaScript-код содержит идентификатор веб-сайта, по которому идет сбор аналитики. Таким образом, вся статистика по работе посетителей с вебсайтом отправляется на сервер Google и становится доступной для анализа.

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

Сервис продолжает собирать аналитику использования мобильного приложения даже тогда, когда мобильное устройство отключено от сети. Разберем на конкретном примере принцип работы Google Analytics в этом контексте. С этой целью создадим тестовое приложение под Android и подключим к нему библиотеку Google Analytics Android SDK (при написании статьи использовалась библиотека версии 3.01).

Анализ решения проблемы отложенной отправки данных

Проведем анализ работы инструментов GoogleAnalytics в режиме оффлайн на примере мобильной платформы Android. Для этого потребуется AndroidSDK, а также IDE (в примере использовалась Android Studio).

Создадим новый проект (с пустым Activity), затем создадим еще одно Activity и снабдим приложение кнопкой для его открытия из главного окна приложения. Оба Activity снабдим обработчиками событий onStart и onStop (реализующими сбор данных для Google Analytics):

protected void onStart()

EasyTracker.getInstance(this).activityStart(this); // Add this method.

protected void onStop()

Подключим, как описывалось ранее, GoogleAnalyticsSDK и запустим приложение (рис. 1). Поскольку в дальнейшем потребуется посмотреть на базу SQLite созданного приложения, необходимо запускать его не на реальном устройстве, а посредством эмулятора. Нажимая на кнопку открытия другого Activity (на рис. 1 это кнопка «AnotherActivity») и кнопку «Назад», предопределенную в операционной системе Android, сгенерируем тем самым исходные данные для GoogleAnalytics. В панели GoogleAnalytics можно удостовериться, что переходы между Activity успешно зафиксированы.

Рис. 1. Тестовое приложение

ф Android Debug Monitor

File Edit Window Help

DDMS 1® Hierarchy View

% Threads Q Heap| Q Allocation Т. ^ Network Sta.. File Explorer ^ Emulator C. " System Info.

|T] GalaxyACE-intel [emulator-5554] com.coollris.media system_process com.android, music com.android.quicksearchbox android, process, a core com. android, inputmethod.latin com. android, deskclock com.android.mms com.android.email com.android. t>l uetooth com.android.protlps com. android, system ui com.android. launcher com.android.voicedialer com. android, phone com.android.providersxalendar android, process, media com. a ndroid.def container com.svox.pico

Name Size Date Time Permissions Info

с- G^ com.android.providers.settings 2014-01-05 11 44 drwxr-x- X

и S? com .an d ro id. providers, subscribedfeeds 2014-01-05 11 44 drwnr-н- X

[> 13 com.android.providers.telephony 2014-01-05 И 44 drwxr-x- X

[> 05 com-android.providers.userdictionary 2014-01-05 11 44 drwKr-K- X

и 123- com.android.provision 2014-01-05 11 44 drwur-H- X

I> com.android.quicksearchbox 2014-03-09 06 06 drwxr-x- X

[> 05 com.android.seiver.vpn 2014-01-05 11 44 drwKr-K- X

и com.android.settings 2014-01-05 11 44 drwur-H- X

б- 05 com.android.soundrecorder 2014 01 05 И 44 drwxr-x- X

[> 05 com.android.spare_pärt[] 2014-01-05 11 44 drwKr-H- X

с- [¿3 com.android.Speechrecorder 2014-01-05 11 44 drwxr-x- X

Ii com.android.systemui 2014 01 05 11 44 drwxr-x- X

ü 05 com.android.term 2014-01-05 И 44 drwxr-x- X

Ii 05 com.android.voicedialer 2014-01-05 11 44 drwxr-x- X

Ii 05 com.ccoliri:.media 2014 01 05 11 45 drwxr-x- X

Ii 05 com.dclouds.childlearning 2014-03-09 07 01 drwxr-x- X

л 05 com.demish.analyticstest.app 2014-03-09 07 02 drwxr-x- X

j 123 databases 2014-02-26 11 46 drwxrwx -X

google_analytics_v2.db 7168 2014-03-09 07 12 -rw-rw--

j files 2014-02-26 11 45 drWXrWX -y

[i| gaClientld 36 2014-02-26 11 45 -rw-rw--

■ & lib 2014-03-09 07 02 drwxr-xr X

> com.eHample.novisa dierbia 2014-03-09 07 01 drwHr-H- X

HI LogCat Ш Console SS

OpenGL Trace View

Рис. 1. File Explorer

hrtjd hrt_time hrturi hrt_string hrt_app_id

31 11394344964517 https: v=18iul=en - us8it=appviewfiiht= 13943449645178isr=3 2 0x480flian=AralyticsTe5t&tid=. 0

32 1394344966484 http:: |v=lßiul=en- ■ u ;Sit=appvi ewßihtz 1394344966484 Eisr=320x480 Bia n = An a lyti с sTestSiti d = UA-484,, 0

33 1394344967003 https: |v=l&ul=en- ■ u sBit= appvi ewBiht= 1394344967003 Bdsr=320x480 Bia n = An a lyti с sTestBiti d = UA-484,, 0

34 1394344967423 https: |v=lßdul=en- ■ u sBit= appvi ewBiht= 1394344967423 Eisr=320x480 Bia n = An a lyti с sTestBiti d = UA-484,, 0

35 1394344967915 http;: |v=lßiul=en- ■ u ;Bit=appvi ewBiht=1394344967915 Bisr=320x480 Sia n = An a lyti с ;Te;tSiti d = UA-404.. 0

36 1394344968369 http;: |v=lßdul=en- ■ u sSit= appvi ewSiht= 1394344968369 Eiir=320x480 Sia n = An a lyti c;Te;tSiti d = UA-484.. 0

37 1394344968857 https: |v=l&ul=en- ■ u ;ßit=appvi ewBihtz 1394344968857 Eisr=320x480 Bia n = An a lyti с sTestSiti d = UA-484,, 0

38 1394345106743 https: |ul = en-üsSiht=1394345106743ßibr=320x480ßisc = startßiaicl = com,demi&h.analyticbte£t,appSicid. 0

39 1394345108103 http;: |v=lßdul=en- ■ u sBit= appvi ewBiht= 1394345108103 Bisr=320x480 Bia n = An a lyti с sTestBiti d = UA-484,, 0

40 1394345108682 https: v=l&ul=en- ■ u sBit=appvi ewBiht=13943451086825isr=320ï480 Bia n = An a lyti с sTestBiti d = UA-404.. 0

41 1394345109090 http;: |v=lßiul=en- ■ u sSit= appvi ewSiht= 1394345109090 Siir=320x480 Sia n = An a lyti c;Te;tSiti d = UA-484.. 0

42 1394345139683 https: |v=lßiul=en- ■ u ;Sit= appvi emrSihtz 1394345139683 Eisr=320x480 Bia n = An a lyti csTestSiti d = UA-484,, 0

43 1394345140236 https: |v=lßiul=en- ■ u ;Sit=appvi ewSihtz 1394345140236 Eisr=320x480 Bia n = An a lyti с sTestSiti d = UA-484,, 0

Рис. 2. Данные таблицы hits2 Google Analytics

Теперь, отключив Интернет от эмулятора Android-устройства (к примеру, включив на нем режим полета), повторное переключение между экранами тестового приложения уже не будет фиксироваться в GoogleAnalytics. Но, тем не менее, в дальнейшем, при подключении сети, эта аналитика все же будет передана на серверы Google. Как это достигается?

i Не можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

Запустив из AndroidStudio инструмент AndroidDebugMonitor, выберем в нем панель FileExplorer. Скопируем базу данных SQLite из эмулятора мобильного устройства на компь-

ютер. Она расположена по адресу Ма!аМа!а//dаtаbаses/google_аnа-lytics_v2.db.

Когда база будет на компьютере, можно открыть ее любым инструментом для работы с SQLite, например, SQLiteManager для Firefox. В базе данных три таблицы:

Первая таблица имеет один атрибут locale, содержащий данные о локализации приложения (в случае рассматриваемого тестового приложения в таблице одна строка со значением «en_US»). Последняя таблица хранит данные об SQL-последовательностях, используемых для значений первичных ключей таблиц базы данных. Наиболее интересна таблица hits2: CREATETABLEhits2 (

'hit_id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,

'hit_time' INTEGER NOT NULL,

'hit_url' TEXT NOT NULL,

'hit_string' TEXT NOT NULL,

Каждая строка в этой таблице - это исходные данные для GoogleAnalytics (рис. 3). В поле hit_time хранится дата зафиксированного события, а его описание располагается в поле hit_string. Описание события представляет собой набор параметров (в том же поле размещается также информация о возникающих в процессе работы приложения исключениях), содержащих такие данные, как:

• тип события (для исключений тут будет «exception);

• разрешение экрана мобильного приложения;

• идентификационный код для GoogleAnalytics;

• другие данные, актуальные для конкретного типа событий. Пример такого описания:

Таким образом, GoogleAnalytics сохраняет в базу данных информацию о работе с приложением в том случае, если нет возможности сразу отправить эту информацию на сервер Google. Когда же эта возможность появляется, вся сохраненная информация отправляется в Google. Кроме того, дата фиксации события на мобильном устройстве не зависит от того, когда информация о событии будет отправлена в GoogleAnalytics. Это позволяет видеть реальную картину использования приложений.

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

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

Синхронизация данных на примере Evernote

Рассмотрим теперь другой, более сложный вариант синхронизации данных на примере популярного мобильного приложения для работы с электронными заметками, которое уже упоминалось ранее, - Evernote.

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

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

Все сущности сервиса описаны при помощи языка описания интерфейсов Apache Thrift 2 [3; 4]. И уже на его основе создан собственный протокол Evernote Data Accessand Management (EDAM) 3.

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

Чтобы построить API при помощи Thrift, необходимо описать используемые сущности при помощи доступных в Thrift типов данных, а также описать в специальной нотации используемые сервисы. Детали проектирования можно изучить в соответствующей литературе [4]. Остановимся подробнее на Evernote.

В Evernote определены следующие сущности:

А также два сервиса с набором методов (перечислены в скобках):

• UserStore (authenticate, refreshAuthentication);

• NoteStore (createNote, createNotebook, createSearch, createTag, deleteNote, deleteNote-book, deleteSearch, deleteTag, getNote, getNoteContent, getNotebook, getResource, getResource-Data, getSearch, getSyncChunk, getSyncState, getTag, listNotebooks, listNotes, listSearches, listTags, updateNote, updateNotebook, updateSearch, updateTag).

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

Получившиеся вследствие кодогенерации Thrif и реализации бизнес-логики API позволяет осуществить взаимодействие с множеством различных приложений. Грамотно спроектированные сущности и сервисы позволяют воспользоваться тем же самым API для реализации алгоритма синхронизации данных на центральном сервере Evernote и клиентскими устройствами.

Алгоритм синхронизации. В документации от Evernote выделены следующие требования к синхронизации.

• Синхронизация осуществляется в клиент-серверном режиме, центральный сервер является основным.

• Клиенты обладают локальной базой данных для хранения информации, так что синхронизация ограничена логическим представлением данных; нет необходимости рассматривать данные на более низком, физическом уровне.

2 Apache. Язык описания интерфейсов Apache Thrift. http://thrift.apache.org/.

3 Corporation, Evernote. Evernote Synchronization via EDAM. 2011.

• Необходимо поддержка полной синхронизации (fullsync) и обмена изменениями (incremental sync) в базе данных; ситуация, в которой каждый сеанс синхронизации представляет собой передачу всей базы данных, недопустима.

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

• Сеанс синхронизации не должен блокировать работу сервиса; допустимы изменения от других клиентов во время сеанса синхронизации.

В Evernote используется так называемый Update Sequence Number (USN). С помощью USN можно упорядочить данные в порядке их изменения. При создании нового аккаунта USN для него инициализируется единицей (точнее, единица будет соответствовать первому созданному объекту). Каждое добавление / изменение / удаление данных в рамках аккаунта характеризуется привязкой к операции USN и увеличением его на единицу.

Для функционирования алгоритма синхронизации на сервере и клиенте используется ряд переменных.

• updateCount - наибольший USN для каждого аккаунта;

• fullSyncBefore - специальная дата, которая позволяет указать на необходимость проведения клиентом обязательной полной синхронизации (full sync); если последняя успешная синхронизация на клиенте была ранее даты fullSyncBefore, то потребуется проведение полной синхронизации.

• lastUpdateCount - значение серверной переменной updateCount при последней синхронизации;

• lastSyncTime - дата последней синхронизации данных (получается с сервера).

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

Пошагово синхронизация выглядит следующим образом.

1. Клиент получает новые и изменившиеся объекты с сервера (с момента последней синхронизации).

2. Клиент согласовывает полученные объекты с локальной базой данных.

3. Клиент отправляет изменения на сервер.

4. Клиент запоминает состояние сервера для последующей синхронизации.

Разрешение конфликтов происходит на клиенте. Для реализации третьего шага измененные на клиенте данные должны помечаться соответствующим флагом «изменен». Более подробная информация об алгоритме синхронизации (оформленная в виде псевдокода) есть в документации для разработчиков.

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

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

• в GoogleAnalitycs осуществляется однонаправленная передача информации с клиента на сервер; каждое сообщение никак не связано с остальными (появление нового сообщения не отражается на сформированных ранее); синхронизация данных сводится к передаче всех сообщений на сервер без какой-либо дополнительной обработки;

• в Evernote реализован алгоритм синхронизации с центральным сервером, позволяющий производить как полную синхронизацию данных, так и обмен изменениями; необходимость в такой реализации диктуется двунаправленным обменом информации - данные модифицируются как на сервере, так и на клиенте.

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

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

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

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

1. РизДж. Облачные вычисления. СПб.: БХВ-Петербург, 2011.

2. Брайан К. Google Analytics для профессионалов (Advanced Web Metrics with Google analytics). 3-е изд. М.: Диалектика, 2013.

3. Agarwal A., Slee M., Kwiatkowski M. Thrift: Scalable Cross-Language Services Implementation. URL: http://thrift.apache.org/static/files/thrift-20070401.pdf/.

4. Randy A. The Programmer's Guide to Apache Thrift. М.: Manning Publication Co, 2013.

5. Fang Hengming, Chen Jia, Xu Bin. The Interaction Mechanism based on JSON for Android Database Application // Information Technology Journal. 2013. Vol. 12. P. 224-228.

6. Ranjeet Singh, Chiranjit Dutta. A Synchronization Algorithm of Mobile // International Journal of Application or Innovation in Engineering & Management (IJAIEM). 2013. Vol. 3, iss. 2. P.491-497.

7. B Sri Ramya, Shirin Bhanu Koduri, M. Seetha. A Stateful Database Synchronization Approach for Mobile Devices // International Journal of Soft Computing and Engineering (IJSCE). 2012. Vol. 2, iss. 3.

Материал поступил в редколлегию 25.09.2014

V. O. Demish, B. N. Pischik

Novosibirsk State University 2 Pirogov Str., Novosibirsk, 630090, Russian Federation

Design Technological Institute of Digital Techniques SB RAS 6Rzhanov Str., Novosibirsk, 630090, Russian Federation

OFFLINE ANDROID APPLICATION AND ALGORITHMS OF DATA SYNCHRONIZATION

This article deals with problem of development mobile applications allowing offline mode (without network connection) with following synchronization sessions. By example of Android ap-

plications described algorithm of data sync used in Google Analytics and Evernote. Denoted actuality of optimization data required for synchronization sessions on mobile devices.

Keywords: mobile platforms, data synchronization, mobile application development, databases.

1. Reese J. Cloud computing. St.-Petersburg, 2011. (in Russ.)

2. Brian K. Google Analytics for professionals (Advanced Web Metrics with Google analytics). Moscow, 2013. (in Russ.)

i Не можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

3. Agarwal A., Slee M., Kwiatkowski M. Thrift: Scalable Cross-Language Services Implementation. URL: http://thrift.apache.org/static/files/thrift-20070401.pdf/.

4. Randy A. The Programmer's Guide to Apache Thrift. Moscow, Manning Publication Co, 2013.

5. Fang Hengming, Chen Jia, Xu Bin. The Interaction Mechanism based on JSON for Android Database Application. Information Technology Journal, 2013, vol. 12, p. 224-228.

6. Ranjeet Singh, Chiranjit Dutta. A Synchronization Algorithm of Mobile. International Journal of Application or Innovation in Engineering & Management (IJAIEM), 2013, vol. 3, iss. 2, p.491-497.

7. B Sri Ramya, Shirin Bhanu Koduri, M. Seetha. A Stateful Database Synchronization Approach for Mobile Devices. International Journal of Soft Computing and Engineering (IJSCE), 2012, vol. 2, iss. 3.

Добавить комментарий

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