English comments for android_mative_app_glue

This commit is contained in:
penggrin12 2026-07-16 15:40:05 +03:00
commit da426f0b53
2 changed files with 154 additions and 154 deletions

View file

@ -1,17 +1,17 @@
/* /*
* Copyright (C) 2010 The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project
* *
* лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия"); * Licensed under the Apache License, Version 2.0 (the "License");
*этот файл можно использовать только в соответствии с лицензией. * you may not use this file except in compliance with the License.
*Копию лицензии можно получить на веб-сайте * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
*Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение * Unless required by applicable law or agreed to in writing, software
* распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ", * distributed under the License is distributed on an "AS IS" BASIS,
* БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* См. лицензию для получения информации об определенных разрешениях по использованию языка и * See the License for the specific language governing permissions and
* ограничениях в рамках лицензии. * limitations under the License.
* *
*/ */
@ -29,7 +29,7 @@
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
/* Для отладочных построений необходимо всегда включать трассировку отладки в этой библиотеке*/ /* For debug builds, always enable the debug traces in this library */
#ifndef NDEBUG #ifndef NDEBUG
# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__)) # define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__))
#else #else
@ -178,7 +178,7 @@ static void android_app_destroy(struct android_app* android_app) {
android_app->destroyed = 1; android_app->destroyed = 1;
pthread_cond_broadcast(&android_app->cond); pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex); pthread_mutex_unlock(&android_app->mutex);
// После этого нельзя изменять объект android_app. // Can't touch android_app object after this.
} }
static void process_input(struct android_app* app, struct android_poll_source* source) { static void process_input(struct android_app* app, struct android_poll_source* source) {
@ -233,7 +233,7 @@ static void* android_app_entry(void* param) {
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Взаимодействие NativeАctivity (вызванное из основного потока) // Native activity interaction (called from main thread)
// -------------------------------------------------------------------- // --------------------------------------------------------------------
static struct android_app* android_app_create(ANativeActivity* activity, static struct android_app* android_app_create(ANativeActivity* activity,
@ -264,7 +264,7 @@ static struct android_app* android_app_create(ANativeActivity* activity,
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&android_app->thread, &attr, android_app_entry, android_app); pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
// Дождитесь запуска потока. // Wait for thread to start.
pthread_mutex_lock(&android_app->mutex); pthread_mutex_lock(&android_app->mutex);
while (!android_app->running) { while (!android_app->running) {
pthread_cond_wait(&android_app->cond, &android_app->mutex); pthread_cond_wait(&android_app->cond, &android_app->mutex);

View file

@ -1,17 +1,17 @@
/* /*
* © 2010 The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project
* *
* Лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия"); * Licensed under the Apache License, Version 2.0 (the "License");
*этот файл можно использовать только в соответствии с лицензией. * you may not use this file except in compliance with the License.
*Копию лицензии можно получить на веб-сайте * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
*Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение * Unless required by applicable law or agreed to in writing, software
* распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ", * distributed under the License is distributed on an "AS IS" BASIS,
* БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* См. лицензию для получения информации об определенных разрешениях по использованию языка и * See the License for the specific language governing permissions and
* ограничениях в рамках лицензии. * limitations under the License.
* *
*/ */
@ -31,138 +31,138 @@ extern "C" {
#endif #endif
/** /**
* Интерфейс NativeActivity, предоставленный <android/native_activity.h>, * The native activity interface provided by <android/native_activity.h>
* основан на наборе предоставленных приложением обратных вызовов, которые вызываются * is based on a set of application-provided callbacks that will be called
*основным потоком действия при возникновении определенных событий. * by the Activity's main thread when certain events occur.
* *
* Это означает, что ни один из данных обратных вызовов _не_ _должен_ блокироваться, иначе * This means that each one of this callbacks _should_ _not_ block, or they
* существует риск принудительного закрытия приложения системой. Эта модель программирования * risk having the system force-close the application. This programming
* прямая, простая, но имеет ограничения. * model is direct, lightweight, but constraining.
* *
* Статическая библиотека threaded_native_app используется для обеспечения другой * The 'threaded_native_app' static library is used to provide a different
* модели выполнения, в которой приложение может реализовать свой собственный цикл главного события * execution model where the application can implement its own main event
* в другом потоке вместо этого. Это работает так: * loop in a different thread instead. Here's how it works:
* *
* 1/ Приложение должно предоставить функцию с именем android_main(), которая * 1/ The application must provide a function named "android_main()" that
* будет вызываться при создании действия в новом потоке, * will be called when the activity is created, in a new thread that is
* отличающемся от основного потока действия. * distinct from the activity's main thread.
* *
* 2/ android_main() получает указатель на допустимую структуру android_app, * 2/ android_main() receives a pointer to a valid "android_app" structure
* которая содержит ссылки на другие важные объекты, например экземпляр объекта * that contains references to other important objects, e.g. the
* ANativeActivity, где выполняется приложение. * ANativeActivity obejct instance the application is running in.
* *
* 3/ Объект android_app содержит экземпляр ALooper, который уже * 3/ the "android_app" object holds an ALooper instance that already
* ожидает две важных вещи: * listens to two important things:
* *
* - событий жизненного цикла действия (например, "pause", "resume"). См. объявления APP_CMD_XXX * - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX
* ниже. * declarations below.
* *
* - входных событий, поступающих из очереди AInputQueue, присоединенной к действию. * - input events coming from the AInputQueue attached to the activity.
* *
* Каждое из этих событий соответствует идентификатору ALooper, возвращенному * Each of these correspond to an ALooper identifier returned by
* ALooper_pollOnce со значениями LOOPER_ID_MAIN и LOOPER_ID_INPUT, * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT,
*, соответственно. * respectively.
* *
* Ваше приложение может использовать тот же ALooper для прослушивания дополнительных * Your application can use the same ALooper to listen to additional
* дескрипторов файла. Они могут быть основаны либо на обратных вызовах, либо поступают с идентификаторами возврата, * file-descriptors. They can either be callback based, or with return
* начинающимися с LOOPER_ID_USER. * identifiers starting with LOOPER_ID_USER.
* *
* 4/ При получении события LOOPER_ID_MAIN или LOOPER_ID_INPUT * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event,
* возвращенные данные будут указывать на структуру android_poll_source. Для нее * the returned data will point to an android_poll_source structure. You
* можно вызвать функцию process() и заполнить android_app->onAppCmd * can call the process() function on it, and fill in android_app->onAppCmd
* и android_app->onInputEvent, для того чтобы они вызывались для вашей собственной обработки * and android_app->onInputEvent to be called for your own processing
* события. * of the event.
* *
* Вместо этого можно вызвать функции нижнего уровня для чтения и обработки * Alternatively, you can call the low-level functions to read and process
* данных непосредственно... посмотрите на реализации process_cmd() и process_input() * the data directly... look at the process_cmd() and process_input()
* в приклеивании, чтобы выяснить, как это делается. * implementations in the glue to see how to do this.
* *
* См. пример "native-activity" в NDK с * See the sample named "native-activity" that comes with the NDK with a
* полной демонстрацией использования. Также посмотрите JavaDoc в NativeActivity. * full usage example. Also look at the JavaDoc of NativeActivity.
*/ */
struct android_app; struct android_app;
/** /**
* Данные, связанные с ALooper fd, которые будут возвращаться как outData * Data associated with an ALooper fd that will be returned as the "outData"
* при готовности данных в этом источнике. * when that source has data ready.
*/ */
struct android_poll_source { struct android_poll_source {
// Идентификатор данного источника. Может быть LOOPER_ID_MAIN или // The identifier of this source. May be LOOPER_ID_MAIN or
// LOOPER_ID_INPUT. // LOOPER_ID_INPUT.
int32_t id; int32_t id;
// android_app, с которым связан данный идентификатор. // The android_app this ident is associated with.
struct android_app* app; struct android_app* app;
// Функция, вызываемая для стандартной обработки данных из // Function to call to perform the standard processing of data from
// этого источника. // this source.
void (*process)(struct android_app* app, struct android_poll_source* source); void (*process)(struct android_app* app, struct android_poll_source* source);
}; };
/** /**
* Это интерфейс стандартного кода приклеивания поточного * This is the interface for the standard glue code of a threaded
* приложения. В этой модели код приложения выполняется * application. In this model, the application's code is running
* в своем собственном потоке, отдельном от основного потока процесса. * in its own thread separate from the main thread of the process.
* Не требуется связь данного потока с ВМ Java * It is not required that this thread be associated with the Java
*, хотя это необходимо для выполнения вызовов JNI любых * VM, although it will need to be in order to make JNI calls any
* объектов Java. * Java objects.
*/ */
struct android_app { struct android_app {
// Приложение может поместить указатель на свой собственный объект состояния // The application can place a pointer to its own state object
// здесь, если нужно. // here if it likes.
void* userData; void* userData;
// Введите здесь код функции для обработки основных команд приложения (APP_CMD_*) // Fill this in with the function to process main app commands (APP_CMD_*)
void (*onAppCmd)(struct android_app* app, int32_t cmd); void (*onAppCmd)(struct android_app* app, int32_t cmd);
// Введите здесь код функции для обработки входных событий. Сейчас // Fill this in with the function to process input events. At this point
// событие уже было предварительно отправлено и будет завершено при // the event has already been pre-dispatched, and it will be finished upon
// возврате. Верните 1, если событие обработано, 0 — для любой диспетчеризации // return. Return 1 if you have handled the event, 0 for any default
// по умолчанию. // dispatching.
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
// Экземпляр объекта ANativeActivity, в котором выполняется это приложение. // The ANativeActivity object instance that this app is running in.
ANativeActivity* activity; ANativeActivity* activity;
// Текущая конфигурация, в которой выполняется это приложение. // The current configuration the app is running in.
AConfiguration* config; AConfiguration* config;
// Это последнее сохраненное состояние экземпляра, предоставленное во время создания. // This is the last instance's saved state, as provided at creation time.
// Значение равно NULL, если состояния не было. Можно использовать это по мере необходимости; // It is NULL if there was no state. You can use this as you need; the
// память останется доступной до вызова android_app_exec_cmd() для // memory will remain around until you call android_app_exec_cmd() for
// APP_CMD_RESUME, после чего она будет освобождена, а savedState получит значение NULL. // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL.
// Эти переменные необходимо изменять только при обработке APP_CMD_SAVE_STATE, // These variables should only be changed when processing a APP_CMD_SAVE_STATE,
// когда их значения будут инициализироваться в NULL и можно будет выполнить malloc для // at which point they will be initialized to NULL and you can malloc your
// состояния и поместить здесь информацию. В этом случае память будет // state and place the information here. In that case the memory will be
// освобождена позднее. // freed for you later.
void* savedState; void* savedState;
size_t savedStateSize; size_t savedStateSize;
// ALooper, связанный с потоком приложения. // The ALooper associated with the app's thread.
ALooper* looper; ALooper* looper;
// Если значение не равно NULL, то это входная очередь, из которой приложение будет // When non-NULL, this is the input queue from which the app will
// получать входные события пользователя. // receive user input events.
AInputQueue* inputQueue; AInputQueue* inputQueue;
// Если значение не равно NULL, то это поверхность окна, в котором приложение может рисовать. // When non-NULL, this is the window surface that the app can draw in.
ANativeWindow* window; ANativeWindow* window;
// Текущий прямоугольник содержимого окна. Это область, в которой // Current content rectangle of the window; this is the area where the
// должно помещаться содержимое окна, чтобы его видел пользователь. // window's content should be placed to be seen by the user.
ARect contentRect; ARect contentRect;
// Текущее состояние действия приложения. Может быть APP_CMD_START, // Current state of the app's activity. May be either APP_CMD_START,
// APP_CMD_RESUME, APP_CMD_PAUSE или APP_CMD_STOP; см. ниже. // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below.
int activityState; int activityState;
// Значение не равно нулю, когда NativeActivity приложения // This is non-zero when the application's NativeActivity is being
// разрушается и ожидает завершения потока приложения. // destroyed and waiting for the app thread to complete.
int destroyRequested; int destroyRequested;
// ------------------------------------------------- // -------------------------------------------------
// Ниже показан "частная" реализация кода прилипания. // Below are "private" implementation of the glue code.
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t cond; pthread_cond_t cond;
@ -186,154 +186,154 @@ struct android_app {
enum { enum {
/** /**
* Идентификатор данных Looper команд, поступающих из основного потока приложения, который * Looper data ID of commands coming from the app's main thread, which
* возвращается как идентификатор от ALooper_pollOnce(). Данные для этого идентификатора * is returned as an identifier from ALooper_pollOnce(). The data for this
* являются указателем на структуру android_poll_source. * identifier is a pointer to an android_poll_source structure.
* Их можно извлечь и обработать с помощью android_app_read_cmd() * These can be retrieved and processed with android_app_read_cmd()
* и android_app_exec_cmd(). * and android_app_exec_cmd().
*/ */
LOOPER_ID_MAIN = 1, LOOPER_ID_MAIN = 1,
/** /**
* Идентификатор данных Looper событий, поступающий из AInputQueue окна * Looper data ID of events coming from the AInputQueue of the
* приложения, который возвращается как идентификатор из * application's window, which is returned as an identifier from
* ALooper_pollOnce(). Данные этого идентификатора являются указателем на структуру * ALooper_pollOnce(). The data for this identifier is a pointer to an
* android_poll_source. Их можно прочитать через объект inputQueue * android_poll_source structure. These can be read via the inputQueue
* приложения android_app. * object of android_app.
*/ */
LOOPER_ID_INPUT = 2, LOOPER_ID_INPUT = 2,
/** /**
* Запуск определяемых пользователем идентификаторов ALooper. * Start of user-defined ALooper identifiers.
*/ */
LOOPER_ID_USER = 3, LOOPER_ID_USER = 3,
}; };
enum { enum {
/** /**
* Команда из основного потока: AInputQueue изменена. После обработки * Command from main thread: the AInputQueue has changed. Upon processing
* этой команды android_app->inputQueue будет обновлена в новую очередь * this command, android_app->inputQueue will be updated to the new queue
* (или NULL). * (or NULL).
*/ */
APP_CMD_INPUT_CHANGED, APP_CMD_INPUT_CHANGED,
/** /**
* Команда из основного потока: новое окно ANativeWindow готово к использованию. После * Command from main thread: a new ANativeWindow is ready for use. Upon
* получения этой команды окно android_app-> будет содержать новую поверхность * receiving this command, android_app->window will contain the new window
*окна. * surface.
*/ */
APP_CMD_INIT_WINDOW, APP_CMD_INIT_WINDOW,
/** /**
* Команда из основного потока: существующее окно ANativeWindow необходимо * Command from main thread: the existing ANativeWindow needs to be
* прекратить. После получения этой команды окно android_app->по-прежнему * terminated. Upon receiving this command, android_app->window still
* содержит существующее окно; после вызова android_app_exec_cmd * contains the existing window; after calling android_app_exec_cmd
* оно получит значение NULL. * it will be set to NULL.
*/ */
APP_CMD_TERM_WINDOW, APP_CMD_TERM_WINDOW,
/** /**
* Команда из основного потока: текущее окно ANativeWindow изменило размер. * Command from main thread: the current ANativeWindow has been resized.
* Перерисуйте согласно новом размеру. * Please redraw with its new size.
*/ */
APP_CMD_WINDOW_RESIZED, APP_CMD_WINDOW_RESIZED,
/** /**
* Команда из основного потока: системе необходимо, чтобы текущее окно ANativeWindow * Command from main thread: the system needs that the current ANativeWindow
* было перерисовано. Необходимо перерисовать окно перед ее передачей в * be redrawn. You should redraw the window before handing this to
* android_app_exec_cmd(), чтобы избежать переходных сбоев рисования. * android_app_exec_cmd() in order to avoid transient drawing glitches.
*/ */
APP_CMD_WINDOW_REDRAW_NEEDED, APP_CMD_WINDOW_REDRAW_NEEDED,
/** /**
* Команда из основного потока: область содержимого окна изменена * Command from main thread: the content area of the window has changed,
* таким образом, что из функционального ввода окно показывается или скрывается. Можно * such as from the soft input window being shown or hidden. You can
* найти новый прямоугольник содержимого в android_app::contentRect. * find the new content rect in android_app::contentRect.
*/ */
APP_CMD_CONTENT_RECT_CHANGED, APP_CMD_CONTENT_RECT_CHANGED,
/** /**
* Команда из основного потока: окно действия приложения получило * Command from main thread: the app's activity window has gained
* фокус ввода. * input focus.
*/ */
APP_CMD_GAINED_FOCUS, APP_CMD_GAINED_FOCUS,
/** /**
* Команда из основного потока: окно действия приложения потеряло * Command from main thread: the app's activity window has lost
* фокус ввода. * input focus.
*/ */
APP_CMD_LOST_FOCUS, APP_CMD_LOST_FOCUS,
/** /**
* Команда из основного потока: изменена текущая конфигурация устройства. * Command from main thread: the current device configuration has changed.
*/ */
APP_CMD_CONFIG_CHANGED, APP_CMD_CONFIG_CHANGED,
/** /**
* Команда из основного потока: системе не хватает памяти. * Command from main thread: the system is running low on memory.
* Попробуйте уменьшить использование памяти. * Try to reduce your memory use.
*/ */
APP_CMD_LOW_MEMORY, APP_CMD_LOW_MEMORY,
/** /**
* Команда из основного потока: действие приложения было запущено. * Command from main thread: the app's activity has been started.
*/ */
APP_CMD_START, APP_CMD_START,
/** /**
* Команда из основного потока: действие приложения было возобновлено. * Command from main thread: the app's activity has been resumed.
*/ */
APP_CMD_RESUME, APP_CMD_RESUME,
/** /**
* Команда из основного потока: приложение должно создать новое сохраненное состояние * Command from main thread: the app should generate a new saved state
* для себя, чтобы восстанавливаться из него позднее в случае необходимости. Если вы сохранили состояние, * for itself, to restore from later if needed. If you have saved state,
* выделите его с использованием malloc и поместите в android_app.savedState с * allocate it with malloc and place it in android_app.savedState with
* размером android_app.savedStateSize. Память будет освобождена * the size in android_app.savedStateSize. The will be freed for you
* позднее. * later.
*/ */
APP_CMD_SAVE_STATE, APP_CMD_SAVE_STATE,
/** /**
* Команда из основного потока: пауза в действии приложения. * Command from main thread: the app's activity has been paused.
*/ */
APP_CMD_PAUSE, APP_CMD_PAUSE,
/** /**
* Команда из основного потока: действие приложения было остановлено. * Command from main thread: the app's activity has been stopped.
*/ */
APP_CMD_STOP, APP_CMD_STOP,
/** /**
* Команда из основного потока: действие приложения уничтожается, * Command from main thread: the app's activity is being destroyed,
* и ожидает очистки потока приложения и выхода перед обработкой. * and waiting for the app thread to clean up and exit before proceeding.
*/ */
APP_CMD_DESTROY, APP_CMD_DESTROY,
}; };
/** /**
* Вызовите, когда ALooper_pollAll() возвращает LOOPER_ID_MAIN, при чтении следующего сообщения команды * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next
*приложения. * app command message.
*/ */
int8_t android_app_read_cmd(struct android_app* android_app); int8_t android_app_read_cmd(struct android_app* android_app);
/** /**
* Вызовите с помощью команды, возвращенной android_app_read_cmd() для выполнения * Call with the command returned by android_app_read_cmd() to do the
* начальной предварительной обработки данной команды. Можно выполнить собственные * initial pre-processing of the given command. You can perform your own
* действия для команды после вызова этой функции. * actions for the command after calling this function.
*/ */
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
/** /**
* Вызовите с помощью команды, возвращенной android_app_read_cmd(), для * Call with the command returned by android_app_read_cmd() to do the
* окончательной предварительной обработки данной команды. Необходимо завершить собственные * final post-processing of the given command. You must have done your own
* действия с командой до вызова этой функции. * actions for the command before calling this function.
*/ */
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
/** /**
* Это функция, которую должен реализовать код приложения, представляет собой * This is the function that application code must implement, representing
* главный вход в приложение. * the main entry to the app.
*/ */
extern void android_main(struct android_app* app); extern void android_main(struct android_app* app);