- Getting started with C++ and Android Native Activities
- Introduction
- Why C++
- What I won’t Cover
- Setup your IDE
- Setup Android Environment for Development
- Java Development Kit(JDK)
- Android SDK/Android Studio/Eclipse
- Setup and Installation of Android Studio
- Closer Look At Android Runtime: DVM vs ART
- What is runtime?
- 1. Assemblers :
- 2. Compilers :
- 3. Interpreters :
- How JAVA code execution works?
- How Android code execution works?
- Just In Time (JIT)
- Ahead Of Time (AOT)
- Why Android use Virtual Machine?
- Benefits of ART
- Drawbacks of ART
- Conclusion
- Процессы и потоки в Android: пишем AsyncTask правильно
Getting started with C++ and Android Native Activities
Introduction
I would like to walk you through setting up a simple Android Native Activity. I will walk through the basic setup, and try to give you the tools you need to move forward.
Although my focus is on games, I will not be telling you how to write an OpenGL application or how to architect your own game engine. That is a discussion that literally fills up books.
Why C++
On Android, the OS and its supporting infrastructure are designed to support applications written in the Java or Kotlin programming languages. Applications written in these languages benefit from tooling embedded deep into the system’s underlying architecture. Many core Android system features, such as the Android UI and Intent handling, are only exposed through Java interfaces.
By choosing to use C++, you are not being “more native” to Android than using a managed language such as Kotlin or Java. Counter intuitively, you are in some ways writing a foreign application with only a subset of Android features available. For most applications, you’re better off with languages like Kotlin.
There are a few exceptions to this rule. Near and dear to my own heart is game development. Since games typically use custom rendering logic, often written in OpenGL or Vulkan, it’s expected that a game looks different from a standard Android application. When you also consider that C and C++ are near universal to every computing platform, and the relative wealth of C libraries to support games development, it may become reasonable to set off down the path of native development.
If you want to make a game from scratch or port over an existing game, Android’s Native Development Kit (or NDK) and its supporting tooling are ready and waiting. In fact, the native activity I’ll be showing you provides an easy one-stop shop in which you can set up an OpenGL canvas and start gathering user input. You may find that despite C’s cognitive overhead, some common code challenges like building vertex attribute arrays from game data become easier in C++ than higher level languages.
What I won’t Cover
I will stop short of showing you how to initialize a Vulkan or OpenGL context. I recommend reading through the samples Google provides, although I will provide some tips to make your life easier. You may opt instead to use a library like SDL or even Google’s FPLBase instead.
Setup your IDE
First we need to make sure that you have everything installed for native development. For this, we need the Android NDK. Launch Android Studio:
Источник
Setup Android Environment for Development
Finally, it’s a showdown time. It’s time to develop your own Android Applications. But wait, where are you going to type your code? You need some environment to develop your apps. Therefore, first you will be required to download the necessary tools, SDKs and setup files to setup the environment for development. You can use a macOS, Windows or a Linux platform for your Android Application Development. All required packages, tools and other required files can be downloaded from the internet. Following are the names of the files, along with their descriptions that you will be required for developing Android apps.
Java Development Kit(JDK)
Android SDK works on Java SE Development Kit(JDK). Therefore, first your system must have JDK installed. If you don’t have it on your system, you can download it from here.
Note: Make sure you download proper JDK based upon your system configurations as there are separate setup files for macOS, Windows and Linux platform.
So the first requirement for setting up the environment is that JDK must be installed on your system. Once you are done with this, you can go for the next step.
Note: Once you have installed JDK, you will also have to set PATH and JAVA_HOME variables. Usually, this is done automatically by the system. Still If you face any problem regarding this, you can read more about it here.
Android SDK/Android Studio/Eclipse
Next comes Android SDK. It contains libraries, debugger, an emulator, documentations, sample codes and tutorials for each API level of the released versions of Android.
Note: Before the release of Android Studio, SDK was a standalone part of the Android Application development tools that could be integrated with other IDE’s like Eclipse with the help of Android ADT Bundle. Later on, Google made Android SDK as a part of the Android Studio, which is the official IDE for Android development.
You can download the complete Android Development Environment bundle(Android Studio + SDK) from the link here.
Setup and Installation of Android Studio
Once you have finished with installing JDK and downloading Android Studio IDE setup file, double click on the .exe file (setup file) of the Android Studio. It’ll prepare the file for setup and will ask you for the location where you want to install it, as shown in image below.
Select an appropriate location and click on Next button.
Click on Install button. It will start installing as shown below.
Click on Next button.
Android Studio has been installed directly and it is ready for use. Click on finish button and Android Studio will open.
Note: If you have installed any previous version of Android Studio, Android Studio setup will first remove your previous version and then it will install the new one, as shown in the images below. Settings and Configurations are not deleted in this process.
Android Studio will automatically get the location of the Android SDK if it is in the same location as itself. But if it fails to discover, then it’ll ask you to browse to the Android SDK’s location.
In the next tutorial, we will talk about the Android SDK manager and the additional packages required in the SDK manager to complete the system setup for development.
Источник
Closer Look At Android Runtime: DVM vs ART
Apr 5, 2017 · 5 min read
Before directly move to Android Runtime, we need to understand what runtime environment is and also understand some basic stuff i.e. the functioning of JVM and Dalvik VM.
What is runtime?
In a simplest term it is a system used by operating system which takes care of converting the code that you write in a high level language like Java to machine code and understand by CPU/Processor.
Runtime comprises of software instructions that execute when your program is running, even if they’re not essentially are a part of the code of that piece of software in particular.
CPUs o r more general term our computers understand only machine language (binary codes) so to make it run on CPU, the code must be converted to machine code, which is done by translator.
So following are the generation of translator in a sequence-
1. Assemblers :
It directly translate assembly codes to machine codes so it was very fast.
2. Compilers :
It translates the code into assembly codes and then use assemblers to translate the code into binary. Using this compilation was slow but execution was fast. But the biggest problem with compiler is that the resulted machine code was platform dependent. In other words the code which runs on one machine may not run on different machine.
3. Interpreters :
It translates the code while executing it. Since the translation happens at runtime, the execution was slow.
How JAVA code execution works?
To maintain the platform independency of the code, JAVA developed JVM i.e. Java Virtual Machine. It developed JVM specific to every platform means JVM is dependency on the platform. The Java compiler converts the .java files into .class files, which is called byte code. This byte code is given to the JVM which converts it into machine code.
This is faster than interpretation but slower than C++ compilation.
How Android code execution works?
In Android Java classes converted into DEX bytecode. The DEX bytecode format is translated to native machine code via either ART or the Dalvik runtimes. Here DEX bytecode is independent of device architecture.
Dalvik is a JIT (Just in time) compilation based engine. There were drawbacks to use Dalvik hence from Android 4.4 (kitkat) ART was introduced as a runtime and from Android 5.0 (Lollipop) it has completely replaced Dalvik. Android 7.0 adds a just-in-time (JIT) compiler with code profiling to Android runtime (ART) that constantly improves the performance of Android apps as they run.
Key Point: Dalvik used JIT (Just in time) compilation whereas ART uses AOT (Ahead of time) compilation.
Below are the code snippet explaining the difference between Dalvik Virtual Machine and Java Virtual Machine.
Just In Time (JIT)
With the Dalvik JIT compiler, each time when the app is run, it dynamically translates a part of the Dalvik bytecode into machine code. As the execution progresses, more bytecode is compiled and cached. Since JIT compiles only a part of the code, it has a smaller memory footprint and uses less physical space on the device.
Ahead Of Time (AOT)
ART is equipped with an Ahead-of-Time compiler. During the app’s installation phase, it statically translates the DEX bytecode into machine code and stores in the device’s storage. This is a one-time event which happens when the app is installed on the device. With no need for JIT compilation, the code executes much faster.
As ART runs app machine code directly (native execution), it doesn’t hit the CPU as hard as just-in-time code compiling on Dalvik. Because of less CPU usage results in less battery drain.
ART also uses same DEX bytecode as input for Dalvik. An application compiled using ART requires additional time for compilation when an application is installed and take up slightly larger amounts of space to store the compiled code.
Why Android use Virtual Machine?
Android makes use of a virtual machine as its runtime environment in order to run the APK files that constitute an Android application. Below are the advantages:
· The application code is isolated from the core OS. So even if any code contains some malicious code won’t directly affect the system files. It makes the Android OS more stable and reliable.
· It provides cross compatibility or platform independency. It meaning even if an app is compiled on platform such as a PC, it can still be executed on the mobile platform using the virtual machine.
Benefits of ART
· Apps run faster as DEX bytecode translation done during installation.
· Reduces startup time of applications as native code is directly executed.
· Improves battery performance as power utilized to interpreted byte codes line by line is saved.
· Improved garbage collector.
· Improved developer tool.
Drawbacks of ART
· App Installation takes more time because of DEX bytecodes conversion into machine code during installation.
· As the native machine code generated on installation is stored in internal storage, more internal storage is required.
Conclusion
ART is written to run multiple virtual machines on low-memory devices by executing DEX files, a bytecode format designed specially for Android that’s optimized for minimal memory footprint. It makes the UI feel more responsive. That’s all from my side. For more details on ART and Dalvik you can go through official Android document.
Thanks for reading. To help others please click ❤ to recommend this article if you found it helpful.
Check out my blogger page for more interesting topics on Software development.
Источник
Процессы и потоки в Android: пишем AsyncTask правильно
Продолжаю свои повествования об Android. И в этот раз хочу поделиться ценной информацией о процессах и потоках, которая должна быть хорошо усвоена и всегда оставаться под рукой во избежании ошибок и недопонимания при написании приложений. В конце статьи приведу пример реализации AsyncTask, который загружает в ImageView картинку по нажатию на кнопку.
Прежде всего отмечу, что подробнее о данной теме можно прочесть в данном руководстве — developer.android.com/guide/topics/fundamentals/processes-and-threads.html
На заметку о процессах и потоках в Android
Когда запускается компонент приложения и приложение не имеет других запущенных компонентов, Android создает новый процесс для приложения с одним потоком исполнения. По умолчанию все компоненты одного приложения запускаются в одном процессе, в потоке называемом «главный». Если компонент приложения запускается и уже существует процесс для данного приложения(какой-то компонент из приложения существует), тогда компонент запущен в этом процессе и использует его поток выполнения. Вы можете изменить данное поведение, задав разные процессы для разных компонентов вашего приложения. Кроме того вы можете добавить потоки в любой процесс.
Задать отдельный процесс для компонента можно с помощью файла манифеста. Каждый тег компонента(activity, service, receiver и provider) поддерживает атрибут android:process. Данный атрибут позволяет задать процесс, в котором будет выполняться компонент. Также вы можете задать процесс в котором будут выполняться компоненты разных приложений. Также данный атрибут поддерживается тегом application, что позволяет задать определенный процесс для всех компонентов приложения.
Android пытается поддерживать процесс приложения как можно дольше, но когда потребуются ресурсы старые процессы будут вытеснены по иерархии важности.
Существует 5 уровней иерархии важности: (процессы первого уровня из списка будут удалены последними)
1.Процесс с которым взаимодействует пользователь(Foreground process)
К таким процессам относится например: активити с которым взаимодействует пользовать; сервис(экземпляр Service), с которым взаимодействует пользователь; сервис запущенный методом startForeground(); сервис, который выполняет один из методов своего жизненного цикла; BroadcastReceiver который выполняет метод onReceive().
2.Видимый процесс
Процесс, в котором не выполнены условия из пункта №1, но который влияет на то, что пользователь видит на экране. К примеру, вызван метод onPause() активити.
3.Сервисный процесс
Служба запущенная методом startService()
4.Фоновый процесс
Процесс выполняемый в фоновом режиме, который невиден пользователю.
Отмечу, что в компонентах приложения существует метод onLowMemory(), но полагаться на то, что данный метод будет вызван нельзя, также как нельзя на 100% полагаться на метод onDestroy(), поэтому логику сохранения данных или каких-либо настроек можно осуществить в методе onStop(), который(как уверяют) точно вызывается.
Когда запускается приложение, система создает «главный» поток выполнения для данного приложения, который также называется UI-потоком. Этот поток очень важен, так как именно в нем происходит отрисовка виджетов(кнопочек, списков), обработка событий вашего приложения. Система не создает отдельный поток для каждого экземпляра компонента. Все компоненты, которые запущенны в одном процессе будут созданы в потоке UI. Библиотека пользовательского интерфейса Android не является потоково-безопасной, поэтому необходимо соблюдать два важных правила:
1) Не блокировать поток UI
2) Не обращаться к компонентам пользовательского интерфейса не из UI-потока
Теперь, предположим, что у нас возникла задача — загрузить картину в ImageView из сети и тут же ее отобразить. Как мы поступим? По логике: мы создадим отдельный поток, который и сделает всю нашу работу, примерно так:
Выглядит правдоподобно, так как мы вынесли операцию загрузки картинки в отдельный поток. Проблема в том, что мы нарушили правило №2. Исправить эту проблему можно с помощью следующих методов:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
К примеру, воспользуемся первым из них:
Теперь реализация потоково-безопасная: сетевая операция выполняется в отдельном потоке, а к ImageView обращаемся из потока UI.
К счастью, данные операции можно объединить с помощью наследования класса Handler и реализации нужной логики, но лучшее решение — наследовать класс AsyncTask.
AsyncTask позволяет выполнить асинхронную работу и делать обновления пользовательского интерфейса.
Для обновления реализуйте метод onPostExecute(), а всю фоновую работу заключите в метод doInBackground(). После того, как вы реализуете свою собственную задачу, необходимо ее запустить методом execute().
Привожу обещанный пример AsyncTask, в котором реализована задача загрузки и отображения картинки(вариант с аннотациями и отклонением от применения стандартного протокола диалогов):
А теперь рассмотрим самый правильный вариант с точки зрения работы с диалогами:
Кода стало побольше, но лучше использовать стандартный протокол работы с диалогами.
Также я убрал все аннотации, чтобы новичкам было проще попробовать данный код.
Не забудьте добавить в свою разметку кнопочки атрибут с указанным значением: android:onClick=«runButtonHandler»
И добавлю: в оффициальном документе(Тыц ) также, как и в моем случае, не используется preExecute(), но если вам понадобится выполнить какие-то действия с вашим пользовательским интерфейсом до начала выполнения задачи, то смело используйте данный метод.
Параметры передаваемые в AsyncTask:
1. Параметры(в нашем случае адрес URL).
2. Прогресс (единицы задающие ход изменения задачи). В нашем случае не используется.
3. Результат выполнения задачи(в нашем случае объект Bitmap)
Код довольно прост: всю фоновую работу мы выполняем в методе doInBackGround(), вызывая метод publishProgress(), чтобы во время загрузки картинки крутился наш ProgressDialog при вызове метода onProgressUpdate(). После выполнения фоновой работы вызывается метод onPostExecute() в который передается результат работы метода doInBackGround(), в нашем случае это объект Bitmap и тут же мы его загружаем в ImageView.
Отмечу пару важных моментов, которые нужно учитывать:
1) Метод doInBackGround() выполняется в фоновом потоке, потому доступа к потоку UI внутри данного метода нет.
2) Методы onPostExecute() и onProgressUpdate() выполняются в потоке UI, потому мы можем смело обращаться к нашим компонентам UI.
Да, я снова применил библиотеку android-annotations, так что не пугайтесь аннотациям.
Хочу отметить важность понимания модели работы процессов в Android, чтобы не допустить ошибок при разработке приложений.
Данная статья это переработка доступной информации + личный опыт при реализации указанной задачи и работе с потоками.
Как всегда пожелания и замечания по поводу материала статьи в личку. Если вам есть что-то добавить или дополнить — смело пишите в комментарии.
UPD Статья обновленна добавлением более правильной версии в плане работы с диалогами.
Источник