ViewModel

Handling Configuration Changes

If we have an activity where we show a user profile and we implemented a web service that can return that data as a LiveData, Which we can safely observe without risking leaking over activity, What happens if the user rotates to the device?

But then the new activity starts, which make a new call.This is OK but not great, We want to retain that data, so the data it holds is immediately available to the next activity or fragment instance. We are already making that request why remake it?

View Model

ViewModel

Lightweight ViewModel which is all of our effort to take out that code outside of your activities and fragments, and put it somewhere else where you can easily test it.The ViewModel class is designed to store and manage UI-related data so that the data survives configuration changes such as screen rotations.

We create this new class it extend the ViewModel class.Whatever data we had inside the activity, we move it into ViewModel class.   

The very first time you make this call, ViewModel will give you a new Instance.When the rotated activity come back, It’s going reconnect to same ViewModel.

ViewModel is the one which prepares the data for the UI and holds on it.This where the data for the UI lives.ViewModel know how to get that data Usually, it has LiveData.It survives configuration changes.

ViewModel

That’s why we put the data into the ViewModel, and it is also the gateway.You can also consider it as your UI controller only ever talks to the ViewModel to reach to the rest of the application.The ViewModel serves as a data store for UI controller.

ViewModel example

The example uses the Architecture components, Retrofit and the Github API. Requires Android Studio 3.0.

Android ViewModel

Adding ViewModel to your Project

Architecture Components are available from Google’s Maven repository. To use them, follow these steps:

Add the Google Maven repository

To add it to your project, open the build.gradle file for your project and add the highlighted line as shown below:

Add Architecture Components

Open the build.gradle file for your app or module and add the artifacts that you need as dependencies:

 

For the example we’ve mentioned above, it would be the ViewModel’s responsibility to acquire and keep the list of users, not the activity or the fragment.ViewModel’s only responsibility is to manage the data for the UI. It should never access your view hierarchy or hold a reference back to the Activity or the Fragment.

It should never reference a View or any class that may hold a reference to the activity context. If the ViewModel needs the Application context, it can extend the AndroidViewModel class and have a constructor that receives the Application in the constructor.

Now we modify UserListsFragment to observe the data and update the UI.

If the activity is re-created, it receives the same UserViewModel instance that was created by the previous activity. When the owner activity is finished, the Framework calls ViewModel’s onCleared() method so that it can clean up resources.

Sharing Data Between Fragments

Imagine a common case of master-detail fragments, where we have a fragment in which the user selects an item from a list and another fragment that displays the contents of the selected item.

ViewModels can be used as a communication layer between different Fragments of an Activity. Each Fragment can acquire the ViewModel using the same key via their Activity. This allows communication between Fragments in a de-coupled fashion such that they never need to talk to the other Fragment directly.

These fragments can share a ViewModel using their activity scope to handle this communication.

Now we modify UserListFragment to share the data.

Notice that both fragments are using getActivity() while getting the ViewModelProvider. This means both of them will receive the same SharedViewModel instance which is scoped to the activity.

Lifecycle of a ViewModel

ViewModel objects are scoped to the Lifecycle passed to the ViewModelProvider when getting the ViewModel. The ViewModel stays in memory until the Lifecycle it’s scoped to goes away permanently—in the case of an activity, once it finishes; in the case of a fragment, once it’s detached.

viewmodel lifecycle

Download this project from GitHub.

Related Post

Lifecycle Aware Components

Room Persistence Library

LiveData

Fragment Tricks

ConstraintLayout 1.1.x

Lifecycle Aware Components

Lifecycles

Lifecycle is the biggest developer pain point. Lifecycle is hard. Lifecycle aware observable things that can do something base on the lifecycle. Your application must respect components lifecycles. Not doing so may trigger memory leaks or even application crashes.

Imagine we have an activity that shows the device location on the screen.

What if myLocationManager.addLocationListener() will be called after myLocationManager.removeLocationListenrer() called, basically keeping the connection forever.

Lifecycle aware component

Components

New lifecycle-aware components provide constructs to tie core components(activity, fragment) of your applications to lifecycle events, removing explicit dependency paths.It can take care of itself. You can just initialize it and forget about it.

Lifecycle

Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.

Lifecycle Components

LifecycleOwner

This is a thing with a lifecycle, it is your activity or your fragment or maybe you have your own UI framework.There as a lifecycle Owner.

LifecycleObserver

LifecycleObserver is the thing that cares about the Lifecycle.Like the LocationManager. It cares about the lifecycle, it wants to stop itself if the lifecycle is not active.

A class can monitor the component’s lifecycle status by adding annotations to its methods.

Now, we initialize MyLocationManager with our Lifecycle(MainActivity) on onCreate and stop worrying about it afterwards. This allows MyLocationManager class to be self sufficient, meaning that it can do its own cleanup when necessary.

Passes the LifecycleOwner as the first argument.

Adding Lifecycle to your Project

Architecture Components are available from Google’s Maven repository. To use them, follow these steps:

Add the Google Maven repository

To add it to your project, open the build.gradle file for your project and add the highlighted line as shown below:

Add Architecture Components

Open the build.gradle file for your app or module and add the artifacts that you need as dependencies:

Order of LifecycleObserver

if observer1 is added before observer2, then ON_CREATE is sent first to observer1, then to observer2 (same happens for ON_START and ON_RESUME), but ON_PAUSE event is sent first to observer2 and only then to observer1 (same for ON_STOP and ON_DESTROY).

 

Download this project from GitHub.

Related Post

ViewModel

Room Persistence Library

LiveData

Fragment Tricks

ConstraintLayout 1.1.x

 

Crashlytics

Fabric

Fabric is a set of tools that help app developer to build and monetize their app. It helps them know who’s using their app and how.

In January 2017, Crashlytics and Fabric were acquired by Google.

Fabric is a modular mobile platform.Fabric is the tool you need to build the best app starting from early development to beyond your release in the app store.Understanding how your app performing out in the app store.Get feedback to be hard but it’s one of the most critical parts of app development to give us confidence that Our customer has a great experience.

The Dashboard that gives you the instantaneous pulse of your app. You can quickly see the most important metrics. It’s clear to pull the status of your app and you are confident because you know how this data is coming to this server and how the analysis is actually run this.

Crashlytics

Crashlytics offers you an organized list of issues ranked and sorted by the impact and the frequency that they’re occurring in the wild.You can quickly focus on the issues that will help you ship crash leaks will highlight file nameline number, and method. So it’s quick for you to know what’s going on. This is super clear and convenient as a developer because this may have been code that you didn’t write or code you just haven’t visited in a while.

Actually, use custom logging which allows you to shrinks in bread crumbs in your code to get a picture of what the user was doing up until the time of the crash.You use this to follow along and try to reproduce the issue on your side for an easier and quicker time to resolution.

However what about it when it’s not what the user doing maybe it’s something contextual about the app when to add debug statement in your app

Crashlytics.log(“Login : skipped login”);

One line of code to send custom logging and custom key and of course, this get sent up with every report so you are never flying blind.

Health Check

You were able to debug a stability issue custom metadata in the crash report that allowed you to quickly fix and redistribute an issue.

One of the great things about fabric is we have a real-time analytics product right alongside a real-time crash aborting product and they talk to get each other and work well together which is great it gives us a lot of metrics about stability that  Understanding of how our app is performing to a whole new level. You can see crash for the user the percentage of our user who has not experienced on the crash.

With the help of the fabric toolset, You were able to use intelligent alerting to quick focus in on a problem that was plaguing our users in the wild.

Integrating Fabric Crashlytics on Android

Crashlytics is the most powerful, yet lightest crash reporting solution. you can implement the Crashlytics in Android with a few clicks.

Step 1: SignUp on Fabric for Crashlytics.

Go to get.fabric.io for signing up on Fabric.io. Click “Get Fabric“.

Step 2: Install Crashlytics Plugin in Android Studio.

File->Settings->Plugins

Install Fabric Plugin

After Click on Browser repositories -> Search “Fabric for Android Studio”->Install

Install Fabric

 

After restarting Android Studio you can find the Fabric icon on the Studio toolbar.

Fabric Icon

Step 4: Adding Crashlytics to Android App.

Open your project in Android Studio, Which you want to add Crashlytics. Now click the Fabric icon on Android Studio toolbar.

Click the “Next” button, then click “Install” next to Crashlytics.

Now Fabric will show the changes that will make in the Android project. Click “Apply”

Please build and run your application.Once app launched fabric will verify Crashlytics is configured for your app.

Cause a Test Crash

You can check to see whether crash reporting has successfully been added simply by throwing an uncaught exception, e.g

Crashes are sent from your app after it’s been reopened.

When looking at your dashboard, you will see a list of issues. Clicking on an individual issue will take you to an issue summary page, with aggregate information about all the crashes (e.g. device type and OS).

Enhance Crash Reports

Crashlytics provides 4 logging mechanisms: logging, custom keys, user information, and caught exceptions.

1.Caught Exceptions

you log caught exceptions in your app’s catch blocks. Add a call to your catch block:

All logged exceptions will appear as “non-fatal” issues in the Fabric dashboard. Your issue summary will contain all the state information you are use to getting from crashes along with breakdowns by Android version and hardware device.

Crashlytics processes exceptions on a dedicated background thread, so the performance impact to your app is minimal. To reduce your users’ network traffic, Crashlytics batches logged exceptions together and sends them the next time the app launches.

2.Custom Logging

Logged messages are associated with your crash data and are visible in the Crashlytics dashboard if you look at the specific crash itself.

3.Custom Keys

Crashlytics allows you to associate arbitrary key/value pairs with your crash reports, which are viewable right from the Crashlytics dashboard. Setting keys are as easy as calling: Crashlytics.setString(key, value) or one of the related methods. Options are:

Crashlytics supports a maximum of 64 key/value pairs.

4 User Information

You can use Crashlytics.setUserId () identifier to provide an ID number, token, or hashed value that uniquely identifies the end-user of your application without disclosing or transmitting any of their personal information. This value is displayed right in the Fabric dashboard.

Related Post

Firebase Performance Monitoring for Android

Memory Leak

 

 

RxJava in Android

A lot of people might already be using Rxjava.It’s quite hard to figure out when you need RxJava.The context for this blog is the little bit test of What RxJava can look like, How you can get started with it, and also show you real life examples.It’s impossible to tell you everything about RxJava in this one blog.

Why Reactive?

The asynchronous source is going to break imperative programming.I don’t mean that it become impossible to write your program with you know the single asynchronous source or multiple. It’s just that the amount of complexity become so much and compounds. Such that it become unmaintained when you get into this like state soup.That’s exactly what we’re going to look at trying to solve.

Typical Code

In above code, Users needs to come from the network or needs to come from a database.Something that you can’t really synchronously call to because you don’t want to block the main thread.In that case, you can resort to a callback interface, but the callback interface has a couple of problems:

  1. It’s hard to control lifecycle.
  2. You can’t generally cancel it.
  3. It’s hard to change multiple callbacks.(if you have to do multiple things you have to coordinate all these callbacks)
  4. There’s no real standard way to do an error handling.
  5. Then there is also the question of what thread is this callback returning? You really want to return the original on the main thread usually.

AsyncTask is sort of solution to that is still not great because there is still the problem of changing and there’s still the problem of error handling.Error handling with AsyncTask is kind of ugly.

Let’s turn it to reactive. We want the user to become a stream of users. So, anytime users updated it’s just going to notify us that there’s a new value.

When we apply RxJava to this problem, we create an observable that returns us, users. Once you invoke this method, nothing is actually executed. It’s setting up a stream where once you subscribe to it, it will start giving you these user objects once you execute, or subscribe to this code.

An observable also has built-in error handling. You can cancel it, it can be either synchronous or asynchronous.Error handling is part of the stream and it propagates through the stream automatically there’s specialize call.Whenever data changed it gets pushed into you.You never have to pull it out.

The Stream

Subscribing is the way to get the data out of these observables. You just have to call this method, then subscribe to it and give it a subscriber. Every time user is produced, we get an onNext event. If something happens, you get an error with a trouble, so it might be any exception, including exceptions that happened when you were handling stuff within your observable. If it’s completed, it will tell you as well.

Subscription

Subscriptions(Disposables) is  kind of like a handle on an active stream and by storing that in some collection we can then use the lifecycle to automatically disconnect from all the streams at the appropriate moment (we can disconnect from that stream and we don’t end up leaking anything)

Unsubscribe

If you are done with a stream, you want to unsubscribe. For example, if you have a fragment or an activity, you’re dealing with lifecycle, you want to cancel the subscription. You want to cancel the observable emitting events. If you don’t unsubscribe, you might leak memory.

Schedulers

If you want to multithreading into your Observable, you can do so by Scheduler operators. The SubscribeOn operator changes this behavior by specifying a different Scheduler on which the Observable should operate. The ObserveOn operator specifies a different Scheduler that the Observable will use to send notifications to its observers.

The SubscribeOn operator designates which thread the Observable will begin operating on, no matter at what point in the chain of operators that operator is called. ObserveOn, on the other hand, affects the thread that the Observable will use below where that operator appears. For this reason, you may call ObserveOnmultiple times at various points during the chain of Observable operators in order to change on which threads certain of those operators operate.

RecyclerView Pagination using Rxjava

A common application feature is to load automatically more items as the user scrolls through the items. This is done by triggering a request for more data once the user crosses a threshold of remaining items before they’ve hit the end.

Define a dependency to RxJava 2.0 and retrofit

Our application to access the network we need to declare the INTERNET permission in the Android manifest file.

We have the following User model class:

Observing Users

One of the most common operations when dealing with asynchronous tasks on Android is to observe the task’s result or outcome on the main thread. With RxJava instead, you would declare you’re Flowable to be observed on the main thread

Now, to use this interface during runtime, we’ll need to build a Retrofit object

CompositeDisposable is a disposable container that can hold onto multiple other disposables and offers add and removal disposable.

PublishProcessor

The subject does not coordinate backpressure for its subscribers and implements a weaker onSubscribe which calls onLoad requests from the incoming Subscriptions. This makes it possible to subscribe the PublishSubject to multiple sources unlike the standard contract on Subscriber.

Due to the nature Flowables are constructed, the PublishProcessor can’t be instantiated through new but must be created via the create() method. Example usage.

Flowable

Flowable is the producer’s class that implemented Publisher.It is introduced from Rxjava2 and provides almost the same function as Observable which exists from Rxjava1. The difference from Observable is that the function of Backpressure is available.

Also, Flowable is a cold producer. A cold producer creates a user stream that informs data every time it is subscribed. Basically, Rxjava deals with cold producers.

Backpressure

Backpressure is a function that controls the amount of data notification. In Rxjava2, only Flowable has this function. Observable does not have this function.

This function uses when notification speed of data is earlier than the processing of receiving side. If the notification speed is faster than the receiving side processing, the processing on the receiving side can not make it in time, and data waiting to be processed accumulates. Backpressure solves this problem.

From Rxjava2, let’s also realize that the function of Backpressure is no longer available in Observable.

concatMap

Maps each value to an Observable, then flattens all of these inner Observables using concatAll.

concatMap is the way that you take item emission and kind turn them into observables that get folded back into the stream.So, once we get that data we put it into you know the network call.concatMap get back into the stream that’s move back to the main thread.

Projects each source value to an Observable which is merged in the output Observable, in a serialized fashion waiting for each one to complete before merging the next.

Returns an Observable that emits items based on applying a function that you supply to each item emitted by the source Observable, where that function returns an Observable. Each new inner Observable is concatenated with the previous inner Observable.

RecyclerView Pagination

A common application feature automatically loads more items as the user scrolls through the items (infinite scroll). This is done by triggering a request for more data once the user crosses a threshold of remaining items before they’ve hit the end.

RecyclerView Pagnation

 

It’s important to fetch data before the user gets to the end of the list. Adding a threshold value. therefore, helps anticipate the need to append more data.

Implementing with RecycleView

Every Adapter  has support for binding to the OnScrollListener events which are triggered whenever user scrolls. Using this, we can define a basic UserPagnation which supports most use cases by creating our own class that extends OnScrollListener.

This is an abstract class, and that in order to use this, you must extend this base class and define the onLoadMoremethod to actually retrieve the new data. For example:

 

Download this project from GitHub.

 

 

Memory Leak

What is a memory leak?

Memory Leak is an object which is application is no longer using, but the Garbage Collection fails to recognize them as unused. The result is that they stay resident in the memory heap.Taking up valuable space that’s never freed for other objects.

Garbage Collection in android

When the amount of memory allocated to app reaches an upper limit a garbage collection event kicked off to free any resource that might no needed.The garbage collector tries to collect everything that is not a GC route  So, if you create an object and remove all references to it, it will be garbage collected, but if you put it in a GC route like a static field, it won’t get garbage collected.onDestroy() is called, it’s going to be garbage collected soon.

Memory Heap in Android

Memory is segmented up into separate spaces based upon what type of allocation is occurring.When allocations in any of the spaces grow a GC event can be kicked off in order to make more room for future allocations.GC event can stop the app events(Quickly eat up app frame time).

Each space has a set of size is allocated.GC keep track or the combined size.As a new object is allocated the of object characteristic are taken into account to best fit what space it should be placed into.

View leak

One of the worst things that can get leaked in your android application is a view object.By themselves, views aren’t much of a leak problem.Rather it’s what they reference that can cause a horrible leak situation.

Views contain a reference back to the activity that created them and activity in turn to reference lots of internal objects and other memory items.This is why a leaked view object is such a big issue.

When the user rotates their device, configuration change will be triggered, causing the current activity to be destroyed.and a new instance of it to be loaded into memory.

But if a view from that first activity was leaked, then the original activity can’t be cleaned up now

How to avoiding leaking view object?

1.Don’t reference view inside of async callbacks.That async event may execute at some point in the future where things aren’t ideal.

2.Don’t reference views from static objects.The issue here is that static objects persist for the lifetime of the entire process that’s running your app, which by the way, is not the same as the lifetime of the activity that declares the static object.As such, having a static object reference to a view can cause issues when the activity is destroyed.

3.Avoid putting views in collections that don’t have clear memory patterns.For example using a WeakHashMap object to store view as values.Since WeakHashMap store view as hard references, you can end up in a bad spot anytime something destroys those views.This type of  WeakHashMap behavior has led it to be nicknamed the leak hashmap.

Why is memory leak bad?

GC event can stop application code from executing in order to properly clean up any resource, that is not being used anymore.Performance problems here come from the fact that missing the memory in your app.These events to kick off that’s heating up your frame time anytime your frame drips about the 16ms second barrier user are going to start to notice.

Memory Churn

Improperly using memory can still kick off a load of performance problems.Allocating too many objects in a short time frame is a clear problem that you should be aware of.Memory churn is when a high number of objects are allocated and potentially freed in a small amount of time.

The quick allocation of so many objects effectively pollutes the recently allocated objects space with a flood of reserved memory blocks.

If you’re noticing in the memory monitor that you’re getting a flood of GC events in a very short time frame then this point to a high chance.

Typically memory churn comes from creating a whole group of a temporary resident object like image or view paint.they repeatedly get created exist a little while and then are freed.This action ends up polluting and fragmenting the memory heap in a very short amount of time resulting in more GC event being kicked off.

Prevent Memory Leak

Allocating new objects in the middle the nested loops or onDraw function of your view.Now the solution here is pretty simple picture code but in order to do that, you need to know where exactly thing is going wrong.

Using memory monitor tool will give you a sense of how your memory working over the lifetime of your application. Every time you see a dip in the allocated memory that see a GC event occurring lots of dips in a really short time frame signals a huge problem.So, for every GC event that you can avoid your app has more time per frame.

A weak reference is a way to access that object without increasing the number of references to it. If there are no more strong references to that object, the weak reference will also be cleared. So, if we make our activity a weak reference, and if at some point we realize the weak reference is cleared, it means that the activity has been garbage collected. However, if it isn’t cleared, we likely have a leak that merits investigation.

The main purpose for weak references is for caches, where they are very useful. They are a way to tell the GC to keep something in memory, but that it can clean them if no one else is using them.

LeakCanary: Detect all memory leaks!

LeakCanary is an open source library that can help put a stop to memory leaks.Instead, we want to focus on how we can detect the leak earlier as it happens while we’re developing the app. That’s where LeakCanary comes in.

How LeakCanary Work?

LeakCanary attaches a pin to things like my Android collectible. The pin knows whether they have been garbage collected or not, and after a while if the pin realizes that it is still not in the trash, it takes a picture of the memory – a heap dump into the file system.LeakCanary then publishes the result so that we can see the memory leak.

We can view the chain of references that are holding the object in memory and preventing it from being garbage collected.

what is going to happen is in for every single leak the top part is always going to object that should be in memory and the bottom part is always going to object that should not be in memory.The key part for you is to identify each of the two zones it’s not going to interleave so top is always green the bottom is always red and the place where it changes is where there’s a bad reference that you need to kill and if you kill bad reference then the object is not connected to GC route anymore and the whole thing can be garbage collected.

Analyzing the Heap

LeakCanary takes all that memory and dumps it to a file, which we then open with a tool to analyze and parse the heap dumps. One of these tools is Memory Analyzer. It basically has all the live objects and classes that were in memory when you took the heap dump. It has a query language called SQL, so you can write something like:

This will give you all the instances where destroyed is true. Once you have found the leaking activities, you can do something that’s called merge_shortest_paths, which computes the shortest paths to the GC root. This will find the backward paths to the objects that are preventing your activity from being garbage collected.

I mention “shortest path” specifically because there are multiple paths from a number of GC routes to any activity or object. For example, my button’s parent view, which also holds a reference to the mContext field.

When we look at a memory leak, we don’t need to look at all the paths; we just want the shortest one. That way, there is less noise, making it easier to find the problem.

LeakCanary Implementation

LeakCanary has a library to parse heap dumps, and implementing it is fortunately very easy. LeakCanary opens the heap dump, load it, parse it, and then find our reference based on the key.LeakCanary obtains that instance, and then just need to parse the graph of objects, work backward, and find the leaking reference.

All that work is actually happening on the Android device. When LeakCanary detects that an activity has been destroyed but not yet garbage collected, it forces a heap dump that gets put on the file system. It then starts a service in a separate process, which will analyze the heap dump and publish the results.

You get is a notification and when you tap it on the notification you get following screen

What is going on a method that nothing gets garbage collected because the entire group of an object is held in memory. The static a singleton here it’s called it’s called a GC root.That’s what I’ve shown as the gray box it’s something that’s never going to be garbage collected.It’s a reference that is never cleared. You could think of static fields you can also think of local variable on threads or references held by native code like a binder.

So, if you wanted to figure out why it’s leaking we have to find a path from those yellow boxes to the activity it’s called a path to GC routes all. In the java memory usually, end up with an infinity of path because there are so many objects that are connected together so you could look at like ten thousand path that’s not very helpful what’s more helpful is if there is let’s say there is only one.

There is one that is the shortest path that is guaranteed to go through that bad reference so it instead of looking at 10,000 paths we can just look at one.we’re going to look at the shortest because that’s’ less information to deal with.

Detecting Memory Leaks Using LeakCanary

Here is an example of a memory leak we found in AsyncTask. Suppose we have an app with the long running task. We have an activity, and at some point, you click on a button and rotate the device.

add the following dependencies in your app build.gradle.

In your Application class:

Create an activity with one Button which is use for executing long running task.

 

The thing here is an activity and onDestroy has been called by android on that activity. So we know that it’s useless at that point and that nothing really needs a to use it and it shouldn’t be in use but it’s still you know holding lot of memory and we want it to be garbage collected and so that activity is held in memory because there’s good pass there’s a bunch of references that eventually reference the activity and that’s why it’s kept in memory the activity is leaking

LeakCanary gives kind of a textual way now this is interesting we identify the object on the path there are supposed  to still be in them in memory and the objects are supposed to be gone and it’s not just going to be one for example maybe top green one is the application class it should stay around forever because identify one should be in memory and one should be not in memory. We can sort of splits are the paths in sort of two area and we can identify the connection creating a problem all

 

Related Post

Firebase Performance Monitoring for Android

Crashlytics

Android NDK

Introduction

Android Native Development Kit (NDK) allow you to embed C/C++ code (native code) into your applications. You can use it to either build from your own source code or take advantage of the existing pre-built native libraries. NDK-build is a shell script that launches the NDK build scripts. These scripts will automatically probe your development system and the application project file in order to determine what to build. They will generate the binaries. and they will copy the binaries into your application’s project path.

Android NDK

NDK provides a tool that allows Java applications to invoke native code and vice versa.

Java Native Interface (JNI)

JNI is a native programming interface, that allows Java code that runs in a virtual machine to interact with applications and libraries written in other programming languages, like C/C++ and assembler. JNI can be used in cases in which the application cannot be fully written in Java. For example, when the Java libraries do not provide support for platform-dependent features.  Another example is when we use an existing library written in another programming language (C/C++). When we want to implement a very efficient code written in a low-level language, such as assembler, for performance reasons.

When an android app uses JNI it loses  advantages of the Java language

  • Java applications are portable, but the native component will not be able to run directly on another platform. We must recompile the native code for that specific platform.
  • Java language is type-safe and secure, but native languages such as C/C++ are not. If a native component makes problems, it can affect the whole application.
  • It is recommended to implement native methods in as few classes as possible. This way, we have a clear isolation between the native code and the Java app

Android NDK example

To compile and debug native code for your app, you need the NDK, CMake, and LLDB.

CMake

Android Studio’s default build tool for native libraries is CMake.An external build tool that works alongside Gradle to build your native library.

LLDB

The debugger Android Studio uses to debug native code.

After installation create new android project

NDK Project

Project structure

 

Create new c++ source files

  1. Right-click on the cpp directory and select New > C++ class.
  2. Enter a name for your source file, such as PrimeNumber.

 

CMake build script

A CMake build script is a plain text file that you must name CMakeLists.Now configure your build script by adding CMake commands. To instruct CMake to create a native library from native source code, add the add_library()commands to your build script.

When you add a source file or library to your CMake build script using add_library()

Hear, we seare PrimeNumber to native-lib.

 

when making changes to your CMake  script file after you have already linked it to Gradle, you should sync Android Studio with your changes by selecting Build > Refresh Linked C++ Projects from the menu bar.

And finally, we can implement the native source code, which contains the native function. We need to include the header file jni.h . We can see in the example that the native function returns a  jboolean(JNI data type).

The name of the function is composed of: The Java_  string  +  file path relative to the top level source directory that contains the Java source code (with underscore instead of slash) +  the name of the Java source code (without the java extension) + the native function name

We have three arguments: 1 JNIEnv * is a pointer to the VM, also called interface pointer  2.jobject is a pointer to the implicit “this” object passed from the Java side.3 Integer number.

The Java source code includes 3 lines

● First of all, you must have a static initializer in which we load the native library.This code will be executed before any other method.

● Then we must declare the native function. We will use the native keyword which tells the virtual machine that the function implementation is found in a shared native library.

● Finally, we can use the native function directly, in this example will check prime number.

 

Download this project from GitHub.