Sunday, April 2, 2017

Android NDK Tutorial


Android Native Development Kit (NDK)


                      Android apps are typically written in Java, with its elegant object-oriented design. However, at times, you need to overcome the limitations of Java, such as memory management and performance, by programming directly into Android native interface. Android provides Native Development Kit (NDK) to support native development in C/C++, besides the Android Software Development Kit (Android SDK) which supports Java.

Passing value from java to C

In Java


private native short passIntReturnInt (int p);

static {
System.loadLibrary("PassingPrimitive");
}
In C

#include <jni.h>
#include <android/log.h>
JNIEXPORT jint JNICALL Java_cookbook_chapter2_PassingPrimitiveActivity_passIntReturnInt(JNIEnv *pEnv, jobject pObj, jint pIntP) {
__android_log_print(ANDROID_LOG_INFO, "native", "%d in %d bytes", pIntP, sizeof(jint));
return pIntP + 1;
}

In Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := PassingPrimitive
LOCAL_SRC_FILES := primitive.c
LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

Manipulating strings in JNI

                        Strings are somewhat complicated in JNI, mainly because Java strings and C strings are internally different. Understanding the basics of encoding is essential to comprehend the differences between Java string and C string. The Unicode Standard is a character coding system designed to support the worldwide interchange, processing, and display of the written texts of the diverse languages and technical disciplines of the modern world. Unicode assigns a unique number for each character it defines, called code point. There are mainly two categories of encoding methods that support the entire Unicode character set, or a subset of it.

                   The first one is the Unicode Transformation Format (UTF), which encodes a Unicode code point into a variable number of code values. UTF-8, UTF-16, UTF-32, and a few others belong to this category. The numbers 8, 16, and 32 refer to the number of bits in one code value. The second category is the Universal Character Set (UCS) encodings, which encodes a Unicode code point into a single code value. UCS2 and UCS4 belong to this category. The numbers 2 and 4 refer to the number of bytes in one code value. 


JNIEXPORT jstring JNICALL Java_cookbook_chapter2_StringManipulationActivity_passStringReturnString(JNIEnv *pEnv, jobject pObj, jstring pStringP){

__android_log_print(ANDROID_LOG_INFO, "native", "print jstring: %s", pStringP);
const jbyte *str;
jboolean *isCopy;
str = (*pEnv)->GetStringUTFChars(pEnv, pStringP, isCopy);
__android_log_print(ANDROID_LOG_INFO, "native", "print UTF-8 string: %s, %d", str, isCopy);

jsize length = (*pEnv)->GetStringUTFLength(pEnv, pStringP);
__android_log_print(ANDROID_LOG_INFO, "native", "UTF-8 string length (number of bytes): %d == %d", length, strlen(str));
__android_log_print(ANDROID_LOG_INFO, "native", "UTF-8 string ends with: %d %d", str[length], str[length+1]);
(*pEnv)->ReleaseStringUTFChars(pEnv, pStringP, str);
char nativeStr[100];
(*pEnv)->GetStringUTFRegion(pEnv, pStringP, 0, length, nativeStr);
__android_log_print(ANDROID_LOG_INFO, "native", "jstring converted to UTF-8 string and copied to native buffer: %s", nativeStr);

const char* newStr = "hello 安卓";
jstring ret = (*pEnv)->NewStringUTF(pEnv, newStr);
jsize newStrLen = (*pEnv)->GetStringUTFLength(pEnv, ret);
__android_log_print(ANDROID_LOG_INFO, "native", "UTF-8 string with Chinese characters: %s, string length (number of bytes) %d=%d", newStr, newStrLen, strlen(newStr));
return ret;

}

Ex : JNIEXPORT void JNICALL Java_cookbook_chapter2_ManagingReferenceActivity_weakReference(JNIEnv *pEnv, jobject pObj, jstring pStringP, jboolean pDelete){
static jstring stStr;
const jbyte *str;
jboolean *isCopy;
if (NULL == stStr) {
stStr = (*pEnv)->NewWeakGlobalRef(pEnv, pStringP);
}
str = (*pEnv)->GetStringUTFChars(pEnv, stStr, isCopy);
if (pDelete) {
(*pEnv)->DeleteWeakGlobalRef(pEnv, stStr);
stStr = NULL;
}
}

Manipulating classes in JNI

Class descriptor: A class descriptor refers to the name of a class or an interface. It can be derived by replacing the "." character in Java with "/" in JNI programming. For example, the descriptor for class java.lang.String is java/lang/String.


FindClass and class loader: The JNI function FindClass has the following prototype:

jclass FindClass(JNIEnv *env, const char *name);

GetSuperclass: The JNI function GetSuperclass has the following prototype:

jclass GetSuperclass(JNIEnv *env, jclass clazz);

Manipulating objects in JNI

Create instance objects in the native code: Four JNI functions can be used to create instance objects of a Java class in the native code, namely AllocObject, NewObject,NewObjectA, and NewObjectV.

The AllocObject function creates an uninitialized object, while the other three methods take a constructor as an input parameter to create the object. The prototypes for the four functions are as follows:


jobject AllocObject(JNIEnv *env, jclass clazz);

jobject NewObject(JNIEnv *env, jclass clazz,jmethodID methodID, ...);

jobject NewObjectA(JNIEnv *env, jclass clazz,jmethodID methodID, jvalue *args);

jobject NewObjectV(JNIEnv *env, jclass clazz,jmethodID methodID, va_list args);

GetObjectClass: This JNI function has the following prototype:

jclass GetObjectClass(JNIEnv *env, jobject obj);


It returns a local reference to the class of the instance object obj. The obj argument must not be NULL, otherwise it will cause the VM to crash.


IsInstanceOf: This JNI function call has the following prototype:
jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz);


Manipulating arrays in JNI

Arrays are represented by jarray or its subtypes such as jobjectArray andjbooleanArray.

Create new arrays: JNI provides NewObjectArray and New<Type>Array functions to create arrays for objects and primitive types. Their function prototypes are as follows:


jarray NewObjectArray(JNIEnv *env, jsize length, jclass elementType, jobject initialElement);

<ArrayType> New<Type>Array(JNIEnv *env, jsize length);

GetArrayLength: This native function has the following prototype:

jsize GetArrayLength(JNIEnv *env, jarray array);

Access object arrays: JNI provides two functions to access object arrays, namelyGetObjectArrayElement and SetObjectArrayElement.

The two functions have the following prototype:

jobject GetObjectArrayElement(JNIEnv *env,jobjectArray array, jsize index);

void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value);

Access arrays of primitive types: void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len, jint* buf);
void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len, jint* buf);

Secondly, if we want to access a large array, then GetIntArrayElements andReleaseIntArrayElements are the JNI functions for us. They have the following prototype: jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy);
void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems, jint mode);

Accessing Java static and instance fields in the native code the access of fields (both static and instance fields) in Java from native code:

jfieldID data type: jfieldID is a regular C pointer pointing to a data structure with details hidden from developers.

Accessing static fields: JNI provides three functions to access static fields of a Java class. They have the following prototypes:

jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
<NativeType> GetStatic<Type>Field(JNIEnv *env,jclass clazz, jfieldID fieldID);

void SetStatic<Type>Field(JNIEnv *env, jclass clazz, jfieldID fieldID,<NativeType> value);

Accessing instance field: Accessing instance fields is similar to accessing static fields. JNI also provides the following three functions for us:


jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

<NativeType> Get<Type>Field(JNIEnv *env,jobject obj, jfieldID fieldID);

void Set<Type>Field(JNIEnv *env, jobject obj, jfieldID fieldID, <NativeType> value);

Calling static and instance methods from the native code

jmethodID data type: Similar to jfieldID, jmethodID is a regular C pointer pointing to a data structure with details hidden from the developers.
Method descriptor: This is a modified UTF-8 string used to represent the input (input arguments) data types and output (return type) data type of the method.



Calling static methods: JNI provides four sets of functions for native code to call Java methods. Their prototypes are as follows:

jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

<NativeType> CallStatic<Type>Method(JNIEnv *env, jclass clazz, jmethodID methodID, ...);

<NativeType> CallStatic<Type>MethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);

<NativeType> CallStatic<Type>MethodV(JNIEnv *env, jclass clazz,jmethodID methodID, va_list args);

Calling instance methods: Calling instance methods from the native code is similar to calling static methods. JNI also provides four sets of functions as follows:

jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

<NativeType> Call<Type>Method(JNIEnv *env, jobject obj, jmethodID methodID, ...);

<NativeType> Call<Type>MethodA(JNIEnv *env,jobject obj, jmethodID methodID, jvalue *args);

<NativeType> Call<Type>MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
Caching jfieldID, jmethodID, and referencing data to improve performance


The first approach caches at the class initializer. In Java, we can have something similar to the following: private native static void InitIDs();
static {
System.loadLibrary(<native lib>);
InitIDs();
}

The second approach caches the IDs at the point of usage. We store the field or method ID in a static variable, so that the ID is valid the next time the native method is invoked.
Checking errors and handling exceptions in JNI

JNI defines two functions to check for exceptions, as follows: jboolean ExceptionCheck(JNIEnv *env);
jthrowable ExceptionOccurred(JNIEnv *env);

When the second function is used, an additional JNI function can be called to examine the details of the exception: void ExceptionDescribe(JNIEnv *env);

There are generally two ways to handle an exception. The first approach is to free the resources allocated at JNI and return. This will leave the responsibility of handling the exception to the caller of the native method.

The second practice is to clear the exception and continue executing. This is done through the following JNI function call: void ExceptionClear(JNIEnv *env);

Throw exceptions in the native code: JNI provides two functions to throw an exception from native code. They have the following prototypes:

jint Throw(JNIEnv *env, jthrowable obj);

jint ThrowNew(JNIEnv *env, jclass clazz, const char *message);

Fatal error: A special type of error is the fatal error, which is not recoverable. JNI defines a function FatalError, as follows, to raise a fatal error:

void FatalError(JNIEnv *env, const char *msg);


Integrating assembly code in JNI

Android NDK allows you to write assembly code at JNI programming. Assembly code is sometimes used to optimize the critical portion of code to achieve the best performance.

Compile assembly $ $ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -S tmp.c -o AssemblyMultiplyDemo.s --sysroot=$ANDROID_NDK/platforms/android-14/arch-arm/

The usage of the assembly code to implement a native method:

Inline assembly at C code: We can write inline assembly code for Android NDK development.

Generating a separate assembly code: One approach to write assembly code is to write the code in C or C++, and use a compiler to compile the code into assembly code. $ $ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -S <c_file_name>.c -o <output_file_name>.s --sysroot=$ANDROID_NDK/platforms/android-<level>/arch-<arch>/

Compile the assembly code: Compiling assembly code is just like compiling C/C++ source code. As shown in the Android.mk file, we simply list the assembly file as a source file as follows:

LOCAL_SRC_FILES := AssemblyMultiplyDemo.s assemblyinjni.c


Building Android NDK applications for different CPU features

Android NDK contains a library named cpufeatures, which can be used to detect the CPU family and optional features at runtime.

Add it in the static library list in Android.mk as follows:

LOCAL_STATIC_LIBRARIES := cpufeatures

At the end of the Android.mk file, import the cpufeatures module:

$(call import-module,cpufeatures)

In the code, include the header file <cpu-features.h>

Get the CPU family. The function prototype is as follows:

AndroidCpuFamily android_getCpuFamily();

It returns an enum. The supported CPU families are listed in the section to follow. ANDROID_CPU_FAMILY_MIPS
ANDROID_CPU_FAMILY_MIPS
ANDROID_CPU_FAMILY_ARM

For the ARM CPU family, the supported CPU feature detections are as follows:
ANDROID_CPU_ARM_FEATURE_ARMv7: It means that the ARMv7-a instruction is supported.
ANDROID_CPU_ARM_FEATURE_VFPv3: It means that the VFPv3 hardware FPU instruction set extension is supported. Note that this refers to VFPv3-D16, which provides 16 hardware FP registers.
ANDROID_CPU_ARM_FEATURE_NEON: It means that he ARM Advanced SIMD (also known as NEON) vector instruction set extension is supported. Note that such CPUs also support VFPv3-D32, which provides 32 hardware FP registers.

Debugging an Android NDK application with logging messages

Android logging system provides a method for collecting logs from various applications into a series of circular buffers. The logcat command is used to view the logs.


mylog.h #include <android/log.h>
#define LOG_LEVEL 9
#define LOG_TAG "NDKLoggingDemo"

#define LOGU(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_UNKNOWN, LOG_TAG, __VA_ARGS__);}
#define LOGD(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_DEFAULT, LOG_TAG, __VA_ARGS__);}
#define LOGV(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);}
#define LOGDE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);}
#define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);}
#define LOGW(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__);}
#define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);}
#define LOGF(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__);}
#define LOGS(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_SILENT, LOG_TAG, __VA_ARGS__);}

#endif

void outputLogs() {
LOGU(9, "unknown log message");
LOGD(8, "default log message");
LOGV(7, "verbose log message");
LOGDE(6, "debug log message");
LOGI(5, "information log message");
LOGW(4, "warning log message");
LOGE(3, "error log message");
LOGF(2, "fatal error log message");
LOGS(1, "silent log message");
}

Debugging an Android NDK application with NDK GDB Android NDK introduces a shell script named ndk-gdb to help one to launch a debugging session to debug the native code.

The application is built with the ndk-build command.
AndroidManifest.xml has the android:debuggable attribute of the<application> element set to true. This indicates that the application is debuggable even when it is running on a device in the user mode. Make sure that the debuggable attribute in AndroidManifest.xml is set to true.

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:debuggable="true"
>

Build the native library with the command "ndk-build NDK_DEBUG=1".


Run the application on an Android device. Then, start a terminal and enter the following command: $ ndk-gdb


Android NDK Multithreading


At Android NDK, POSIX Threads(pthreads) is bundled in Android's Bionic C library to support multithreading. This chapter mainly discusses the API functions defined in the pthread.h and semaphore.h header files,

Thread creation
Syntax : int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
void pthread_exit(void *value_ptr);
int pthread_join(pthread_t thread, void **value_ptr);

Ex: void jni_start_threads() {
pthread_t th1, th2;
int threadNum1 = 1, threadNum2 = 2;
int ret;
ret = pthread_create(&th1, NULL, run_by_thread, (void*)&threadNum1); // run_by_thread is function name
ret = pthread_create(&th2, NULL, run_by_thread, (void*)&threadNum2);
void *status;
ret = pthread_join(th1, &status);
int* st = (int*)status;
LOGI(1, "thread 1 end %d %d", ret, *st);
ret = pthread_join(th2, &status);
st = (int*)status;
LOGI(1, "thread 2 end %d %d", ret, *st);
}

Why we need Synchronizing
As per operating system terminology, mutex and semaphore are kernel resources that provide synchronization services (also called as synchronization primitives).

The producer-consumer problem:

Note that the content is generalized explanation. Practical details vary with implementation.

Consider the standard producer-consumer problem. Assume, we have a buffer of 4096 byte length. A producer thread collects the data and writes it to the buffer. A both the threads should not run at the same time.consumer thread processes the collected data from the buffer. Objective is,Using Mutex:

A mutex provides mutual exclusion, either producer or consumer can have the key (mutex) and proceed with their work. As long as the buffer is filled by producer, the consumer needs to wait, and vice versa.

At any point of time, only one thread can work with the entire buffer. The concept can be generalized using semaphore.

Using Semaphore:

A semaphore is a generalized mutex. In lieu of single buffer, we can split the 4 KB buffer into four 1 KB buffers (identical resources). A semaphore can be associated buffers at the same time.with these four buffers. The consumer and producer can work on different Strictly speaking, a mutex is locking mechanism used to synchronize access to a resource. Only one task (can be a thread or process based on OS abstraction) can acquire the mutex. It means there is ownership associated with mutex, and only the owner can release the lock (mutex).


Semaphore is signaling mechanism (“I am done, you can carry on” kind of signal). For example, if you are listening songs (assume it as one task) on your mobile and at the same time your friend calls you, an interrupt is triggered upon which an interrupt service routine (ISR) signals the call processing task to wakeup.

Mutex:

Is a key to a toilet. One person can have the key - occupy the toilet - at the time. When finished, the person gives (frees) the key to the next person in the queue.

Officially: "Mutexes are typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section." Ref: Symbian Developer Library

(A mutex is really a semaphore with value 1.)

Semaphore:

Is the number of free identical toilet keys. Example, say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue.


Officially: "A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore)." Ref: Symbian Developer Library

Synchronizing native threads with mutex at Android NDK

A mutex can be initialized with the pthread_mutex_init function, which has the following prototype: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

USING THE MUTEX

The following four functions are available to lock and unlock a mutex: int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs);

int cnt = 0;
int THR = 10;
void *run_by_thread1(void *arg) {
int* threadNum = (int*)arg;
while (cnt < THR) {
pthread_mutex_lock(&mux1);
while ( pthread_mutex_trylock(&mux2) ) {
pthread_mutex_unlock(&mux1); //avoid deadlock
usleep(50000); //if failed to get mux2, release mux1 first
pthread_mutex_lock(&mux1);
}
++cnt;
LOGI(1, "thread %d: cnt = %d", *threadNum, cnt);
pthread_mutex_unlock(&mux1);
pthread_mutex_unlock(&mux2);
sleep(1);
}
}

Synchronizing native threads with conditional variables at Android NDK pthread_mutex_t mux;
pthread_cond_t cond;
void jni_start_threads() {
pthread_t th1, th2;
int threadNum1 = 1, threadNum2 = 2;
int ret;
pthread_mutex_init(&mux, NULL);
pthread_cond_init(&cond, NULL);
ret = pthread_create(&th1, NULL, run_by_thread1,
void*)&threadNum1);
LOGI(1, "thread 1 started");
ret = pthread_create(&th2, NULL, run_by_thread2,
void*)&threadNum2);
LOGI(1, "thread 2 started");
ret = pthread_join(th1, NULL);
LOGI(1, "thread 1 end %d", ret);
ret = pthread_join(th2, NULL);
LOGI(1, "thread 2 end %d", ret);
pthread_mutex_destroy(&mux);
pthread_cond_destroy(&cond);
}


int cnt = 0;
int THR = 10, THR2 = 5;
void *run_by_thread1(void *arg) {
int* threadNum = (int*)arg;
pthread_mutex_lock(&mux);
while (cnt != THR2) {
LOGI(1, "thread %d: about to wait", *threadNum);
pthread_cond_wait(&cond, &mux);
}
++cnt;
LOGI(1, "thread %d: cnt = %d", *threadNum, cnt);
pthread_mutex_unlock(&mux);
}

Programming with the dynamic linker library in Android NDK


Dynamic loading is a technique to load a library into memory at runtime, and execute functions or access variables defined in the library. It allows the app to start without these libraries. void naDLDemo(JNIEnv* pEnv, jclass clazz) {
void *handle;
double (*sqrt)(double);
const char *error;
handle = dlopen("libm.so", RTLD_LAZY);
if (!handle) {
LOGI(1, "%s\n", dlerror());
return;
}
dlerror(); /* Clear any existing error */
*(void **) (&sqrt) = dlsym(handle, "sqrt");
if ((error = dlerror()) != NULL) {
LOGI(1, "%s\n", error);
return;
}
LOGI(1, "%f\n", (*sqrt)(2.0));
}

Add an Android.mk file under the jni folder with the following content:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := DynamicLinker
LOCAL_SRC_FILES := DynamicLinker.cpp
LOCAL_LDLIBS := -llog -ldl
include $(BUILD_SHARED_LIBRARY)


The following functions are defined in the dlfcn.h header file by the Android dynamic linking library: void* dlopen(const char* filename, int flag);
int dlclose(void* handle);
const char* dlerror(void);
void* dlsym(void* handle, const char* symbol);
int dladdr(const void* addr, Dl_info *info);

Understand the Android.mk files

Android NDK provides an easy-to-use build system, which frees us from writing makefiles. However, we still need to provide some basic inputs to the system through Android.mk and Application.mk.

The Android.mk file is a GNU makefile fragment that describes the sources to the Android build system. The sources are grouped into modules. Each module is a static or shared library. The Android NDK provides a few predefined variables and macros.

CLEAR_VARS: This variable points to a script, which undefines nearly all module description variables except LOCAL_PATH include $(CLEAR_VARS)

BUILD_SHARED_LIBRARY: This variable points to a build script, which determines how to build a shared library from the sources listed, based on the module description. We must have LOCAL_MODULE and LOCAL_SRC_FILES defined when including this variable, as follows:

include $(BUILD_SHARED_LIBRARY)

my-dir: The my-dir macro returns the path of the last included makefile, which is usually the directory containing the current Android.mk file. It is typically used to define the LOCAL_PATH, as follows:

LOCAL_PATH := $(call my-dir)

all-subdir-makefiles: This macro returns a list of Android.mk files located in all subdirectories of the current my-dir path. include $(call all-subdir-makefiles)

LOCAL_PATH: This is a module description variable, which is used to locate the path to the sources. It is usually used with the my-dir macro, as follows:

LOCAL_PATH := $(call my-dir)

LOCAL_MODULE: This is a module description variable, which defines the name of our module.

LOCAL_SRC_FILES: This is a module description variable, which lists out the sources used to build the module.

LOCAL_C_INCLUDES: This is an optional module description variable, which provides a list of the paths that will be appended to the include search path at compilation. LOCAL_C_INCLUDES := $(LOCAL_PATH)/../libbmp/

LOCAL_SHARED_LIBRARIES: This is an optional module description variable, which provides a list of the shared libraries the current module depends on. LOCAL_SHARED_LIBRARIES := libbmp

LOCAL_LDLIBS: This is an optional module description variable, which provides a list of linker flags. It is useful to pass the system libraries with the -l prefix. LOCAL_LDLIBS := -llog

Using a library as a prebuilt library

The content of this Android.mk file is as follows:

 1
2
3
4
5
6
7
8
9
10
11
12
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libbmp-prebuilt
LOCAL_SRC_FILES := libbmp-0.1.3/lib/libbmp.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/libbmp-0.1.3/include/
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := PortingWithBuildSystem
LOCAL_SRC_FILES := PortingWithBuildSystem.c
LOCAL_STATIC_LIBRARIES := libbmp-prebuilt
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

Share:

Tuesday, November 15, 2016

Workout Guide: Fitness guide for Weight tracking, gym workouts and exercise, running and diet.




           Workout Guide is a fitness guide for someone who wants to track weight , workouts and running. Workout Guide helps you to reach your fitness goals. Workout Guide has many exercises and workouts for training at your gym or at home. App also is fitness training guide.


Workout Guide has the following sections:
Profile Helps you to view your progress of weight gain or loss.

Weight Statistics
Provides visual graph of your weight gain or loss progress

Gym Routine
You can create Different workouts routines that will help you to schedule your weekly work.


Gym Workout
Different guided workouts that will allow you to build body at Gym or home.

Gym Exercises
More than 100 different exercises to do at the gym with description of the exercise, info about involved muscles and images.

Running
This screen will help you to track your distance run accurately using GPS.


Diet
This screen will help you support your work in the gym with nutrition advice so that you know what, when and how to eat to achieve your goals.


App also explains how to use the fitness equipment’s and different fitness exercise which can be done at home and in gym.
This app is free, we only ask you for your positive rating so that more people knows the app and we can keep improving it.
Download Workout guide from Playstore 

Share:

Wednesday, November 2, 2016

Goal Settings to achieve success in life


               Setting goals helps you choose where you want to go in life. By knowing precisely what you want to achieve, you know where you have to concentrate your efforts. Setting goals gives you long-term vision and short-term motivation

                First you create your "big picture" of what you want to do with your life (or over, say, the next 10 years), and identify the large-scale goals that you want to achieve. Then, you break these down into the smaller and smaller targets that you must hit to reach your lifetime goals. Finally, once you have your plan, you start working on it to achieve these goals.

Following are the areas were you can set goals

  • Career – What level do you want to reach in your career, or what do you want to achieve?
  • Financial – How much do you want to earn, by what stage? How is this related to your career goals? 
  • Education – Is there any knowledge you want to acquire in particular? What information and skills will you need to have in order to achieve other goals? 
  • Family – Do you want to be a parent? If so, how are you going to be a good parent? How do you want to be seen by a partner or by members of your extended family? 
  • Artistic – Do you want to achieve any artistic goals? 
  • Attitude – Is any part of your mindset holding you back? Is there any part of the way that you behave that upsets you? (If so, set a goal to improve your behavior or find a solution to the problem.) 
  • Physical – Are there any athletic goals that you want to achieve, or do you want good health deep into old age? What steps are you going to take to achieve this? 
  • Pleasure – How do you want to enjoy yourself? (You should ensure that some of your life is for you!) 
  • Public Service – Do you want to make the world a better place? If so, how?
           Once you have set your lifetime goals, set a five-year plan of smaller goals that you need to complete if you are to reach your lifetime plan.  Then create a one-year plan, six-month plan, and a one-month plan of progressively smaller goals that you should reach to achieve your lifetime goals. Each of these should be based on the previous plan.
Then create a daily To-Do List of things that you should do today to work towards your lifetime goals

Goals should be SMART  

· S – Specific (or Significant).
· M – Measurable (or Meaningful).
· A – Attainable (or Action-Oriented).
· R – Relevant (or Rewarding).
· T – Time-bound (or Trackable).

Share:

How to generate great ideas


Following are some of the tips to generate great ideas

Connecting Dots from Disparate Fields : What if we combine this one existing idea/product with another existing idea/product to solve a problem?

Expanded Knowledge Base : Creativity is about connecting the dots. The more dots you have to work with, the more combinations available to help generate new ideas. Curiosity generates more knowledge (dots), which precedes creativity. Creative people always ask why and continuously question the assumptions behind the existing business models, product designs, and business processes.One thing we know about creativity is that it typically occurs when people who have mastered two or more quite different fields use the framework in one to think afresh about the other.
Imagination is the right brain asking what if by connecting dots in imaginative ways, as reflected by Einstein’s quote, “Imagination is more important than knowledge. Knowledge is limited. Imagination encircles the world.”

Nominal Stress (Creative Tension) : For the violin string to produce the right tone it needs the right amount of stress. Under too much tension the string snaps; without any tension, it does not produce any music. Similarly the mind needs creative tension. Creative tension is the gap between where we are and where we want to be.

Takes Time : Creative problem solving requires time to engage the mind in exploring what if before locking into how to. Also, it takes time to develop a raw creative idea and get it ready for implementation.

Stay curious : Every year ask yourself, “How am I more valuable to my organization than I was a year ago? Make a habit of asking questions. Seek assignments beyond your job description. Attend industry conferences outside your field. Take full advantage of every learning opportunity every experience is a building block to a creative life.


Few other tips :

  • Developing creative ideas requires persistence. 
  • Engage in Observation Sessions 
  • Socialize Outside Your Normal Circles
  • Read More Books
  • Randomly Surf the Web
  • Keep a Regular Journal
  • Meditate

Share:

How to develop Intellectual Curiosity


      If we want to grow intellectually, morally, socially, and spiritually, we need to ask questions and seek answers. We need intellectual curiosity. The intellectually curious person has a deep and persistent desire to know. She asks and seeks answers to the “why” questions. And she doesn’t stop asking at a surface level, but instead asks probing questions in order to peel back layers of explanation to get at the foundational ideas concerning a particular issue. 
Curiosity is an important trait of a genius. I don’t think you can find an intellectual giant who is not a curious person. Thomas Edison, Leonardo da Vinci, Albert Einstein, Richard Feynman, they are all curious characters 
Some tips to develop it 
1. Keep an open mind : This is essential if you are to have a curious mind. Be open to learn, unlearn, and relearn. Some things you know and believe might be wrong, and you should be prepared to accept this possibility and change your mind. 
2. Don’t take things as granted : If you just accept the world as it is without trying to dig deeper, you will certainly lose the ‘holy curiosity’. Never take things as granted. Try to dig deeper beneath the surface of what is around you. 
3. Ask questions relentlessly : A sure way to dig deeper beneath the surface is asking questions: What is that? Why is it made that way? When was it made? Who invented it? Where does it come from? How does it work? What, why, when, who, where, and how are the best friends of curious people. 
4. Don’t label something as boring : Whenever you label something as boring, you close one more door of possibilities. Curious people are unlikely to call something as boring. Instead, they always see it as a door to an exciting new world. Even if they don’t yet have time to explore it, they will leave the door open to be visited another time. 
5. See learning as something fun : If you see learning as a burden, there’s no way you will want to dig deeper into anything. That will just make the burden heavier. But if you think of learning as something fun, you will naturally want to dig deeper. So look at life through the glasses of fun and excitement and enjoy the learning process.
6. Read diverse kinds of reading : Don’t spend too much time on just one world; take a look at another worlds. It will introduce you to the possibilities and excitement of the other worlds which may spark your interest to explore them further. One easy way to do this is through reading diverse kinds of reading. Try to pick a book or magazine on a new subject and let it feed your mind with the excitement of a new world.
Share:

Monday, October 31, 2016

How to find your passion


  • Choose a subject on which you have a deep passion. You'll know you are passionate about a subject if you devote your most precious resource to it. Time.
  • What do you love to spend time doing, learning, watching or studying? What would you do even if you weren't going to get paid for doing it? What is a hobby or an avid interest that you have been following for some time that has caused you to make some distinctions others would not have made? What is a subject you have invested your own hard-earned money on to experience, or to evolve your ability
  • Select a topic you are willing to practice day and night to perfect, making finer and finer distinctions. Choose a subject that would not feel like work to you to make those distinctions but instead would feel like play. Top sportspeople put in what would seem to others like painstaking hours of practicing, but these people live in the ‘forward’. They project themselves into the future and see the very moment when the practice will pay off for the biggest reward. When the clock is counting down and it's going down to the wire for them, that's the time they planned for, and they seize the moment and create history.
  • Is there a subject on which you have high levels of natural ability? For others it may seem difficult or even impossible, but for you it's easy to perform better than others? You may not even know at this point why or how you find it easy, but you just do. Other people will probably have voiced how gifted you seem or maybe they even called you lucky.
  • It is very important to choose a subject that fits your personality type. Without doubt, the best profiling tool I have come across is Talent Dynamics. I thoroughly recommend doing this not just for you, but also for the people you will employ as part of your team. Making sure you select the right people for the right job is crucial in building a world-class team and building a successful ‘expert’ business.
  • Finally, once you think you have found your subject, the last sanity check is to establish if there are good profits to be made from the subject. You'll need to be sure that there are people who are hunting for information to master the subject themselves or to solve a problem that they have. Remember, all businesses must sell a product or service to make profit, and all products or services must solve a problem or enhance people's lives to be of value. Also, consider the longevity of the subject. Will it be a passing fad or an evergreen topic that people will always want solutions for?
Share:

Building Hybrid Apps with AngularJS and Ionic

Building Hybrid Apps with AngularJS and Ionic


             A hybrid app is a type of mobile app that uses a browser window to display its interface. Ionic is a combination of tools and utilities that enables developers to quickly build hybrid mobile apps using the same technologies used to build websites and web applications, primarily HTML, CSS (Cascading Style Sheets), and JavaScript.

         Ionic works by embedding a web application inside of a native app by using Cordova. It’s designed to work together with Angular to create a web application for the mobile environment, and includes support for mobile features like user interface controls and responding to touch input.


WHAT IS IONIC

Ionic is a combination of technologies and utilities designed to make building hybrid mobile apps fast, easy, and beautiful. Ionic is built on an ecosystem that includes Angular as the web application framework and Cordova for building and packaging the native app.

 
Device — This loads the app. The device contains the operating system that manages the installation of apps that are downloaded from the platform’s store. The operating system also provides a set of APIs for apps to use to access various features, such as the GPS location, contacts list, or camera.

Cordova app wrapper— This is a native app that loads the web application code. Cordova is a platform for building mobile apps that can run using HTML, CSS, and JavaScript inside of a native app, which is known as a hybrid mobile app. It’s a utility for creating a bridge between the platform and the application. It creates a native mobile app that can be installed (called the app wrapper in figure 1.1), and it contains what’s called a WebView (essentially an isolated browser window) with a JavaScript API that the web application will run inside.

Cordova JavaScript API— This is the bridge that communicates between the app and the device. The app wrapper has access to both the web application and the native platform through the JavaScript API.
Angular— This is the web application that controls the app routing and function. The Angular web application runs inside of the WebView. Angular is a very popular framework for building powerful web applications. Angular is primarily used to manage the web application’s logic and data.

Ionic— This provides the user interface components rendered in the app. Ionic is built on top of Angular, and is primarily used to design the user interface and experience. This includes the visual elements such as tabs, buttons, and navigation headers.


TYPES OF MOBILE EXPERIENCES


There are three basic types: 

  • Native apps, 
  • Mobile websites, 
  • Hybrid apps.

Native mobile apps

To create native apps, developers write code in the default language for the mobile platform, which is Objective C or Swift for iOS and Java for Android. Developers compile the app and install it on a device. Using the platform software development kit (SDK), the app communicates with the platform APIs to access device data or load data from an external server using HTTP requests.

Native app advantages

  • Native APIs— Native apps can use the native APIs directly in the app, making the tightest connection to the platform.
  • Performance— They can experience the highest levels of performance.
  • Same environment— They’re written with native APIs, which is helpful for developers familiar with the languages used.

Native app disadvantages

  • Language requirements— Native apps require developer proficiency in the platform language (for example, Java) and knowledge of how to use platform-specific APIs.
  • Not cross-platform— They can only be developed for one platform at a time.
  • High level of effort— Typically, they require more work and overhead to build, which increases costs.

Mobile websites (web apps)

Mobile websites, or web apps, work well on a mobile device and are accessed through a mobile browser. Web apps are websites viewed on a mobile device in a mobile browser, designed specifically to fit a mobile device screen size.

Mobile website advantages

  • Maintainability— Mobile websites are easy to update and maintain without the need to go through an approval process or update installations on devices.
  • No installation— Because they exist on the internet, they don’t require installation on mobile devices. 
  • Cross-platform— Any mobile device has a browser, allowing your application to be accessible from any device.

Mobile website disadvantages

  • No native access— Because mobile websites are run in the browser, they have no access to the native APIs or the platform, just the APIs provided by the browser.
  • Require keyboard to load— Users have to type the address in a browser to find or use a mobile website, which is more difficult than tapping an icon.
  • Limited user interface— It’s difficult to create touch-friendly applications, especially if you have a responsive site that has to work well on desktops.
  • Mobile browsing decline— The amount of time users browse the web on a mobile device is declining, while app use is increasing.


Hybrid apps

A hybrid app is a mobile app that contains an isolated browser instance, often called aWebView, to run a web application inside of a native app. It uses a native app wrapper that can communicate with the native device platform and the WebView. This means web applications can run on a mobile device and have access to the device, such as the camera or GPS features.

Hybrid app advantages


  • Cross-platform— You can build your app once and deploy it to multiple platforms with minimal effort.
  • Same skills as web development— They allow you to build mobile apps using the same skills already used to develop websites and web applications.
  • Access to device— Because the WebView is wrapped in a native app, your app has access to all of the device features available to a native app.
  • Ease of development— They’re easy and fast to develop, without the need to constantly rebuild to preview. You also have access to the same development tools used for building websites.


Hybrid app disadvantages

  • WebView limitations— The application can only run as well as the WebView instance, which means performance is tied to the quality of the platform’s browser.
  • Access native features via plugins— Access to the native APIs you need may not be currently available, and may require additional development to make a plugin to support it.
  • No native user interface controls— Without a tool like Ionic, developers would have to create all of the user interface elements.


Angular: web application framework


                             Angular (also known as AngularJS) is a Google open source project that has become quite popular with web application developers. It provides web developers a good application structure and the ability to write complete applications quickly.

Cordova: hybrid app framework

             This is the layer that takes care of managing the communication between the browser window and native APIs. The weather-app example needs access to the device’s GPS information to know what location to load data for, and Cordova is able to bridge the gap between Angular and the device to retrieve that information.

                  You may also have heard of PhoneGap. Adobe contributed PhoneGap to the Apache Software Foundation under the name Cordova. Cordova is an open source Apache project that has a large community around it. Adobe continues to be a major developer of the framework. Cordova is licensed under the Apache 2.0 license.

PREREQUISITES FOR BUILDING APPS WITH IONIC

  •  Experience with HTML, CSS, and JavaScript
  •  Experience with web applications and Angular
  •  Access to a mobile device


Setting up your development environment


Make sure you have installed git. If not download
Install Node.js

Node.js (often referred to as Node) is a platform that runs JavaScript outside of the browser. It allows developers to create applications written in JavaScript that can then execute anywhere. 

 $ node –v v0.12.0

Install Ionic CLI and Cordova


This command uses the Node package manager (npm) to install and set up your command-line interface (CLI) tools. $ npm install –g cordova ionic
$ cordova –v 4.2.0
$ ionic –v 1.3.14

To update to latest versions
$ npm update –g ionic
$ npm update –g cordova


Starting a new project Ionic provides a simple start command that allows you to set up a new project
Run the following commands to create a new project and then to change into the new directory
$ ionic start chapter2
$ cd chapter2

Previewing in a browser You can preview your app in the browser, which makes it very easy to debug and develop without having to constantly build the project on a device or emulator.

The following command will start a simple server, open the browser, and even autorefresh the browser when you save a file change:

$ ionic serve
It may prompt you to choose an address, and in most cases you should select localhost. It will open the default browser on your computer on port 8100. You can visit http://localhost:8100 in any browser, but it’s best to preview using a browser used by the platform you’re targeting because that’s the browser the WebView uses.

Make sure you have Android or iOS simulator setup or real device connected.

Adding a platform to the project

These two commands will create project files for iOS and Android, respectively: $ ionic platform add ios
$ ionic platform add android

Previewing in an emulator

If you’re on a Mac and emulating on iOS, you’ll also need to install ios-sim: $ npm install -g ios-sim

Now you can run the app in an emulator using the emulate command: $ ionic emulate ios
$ ionic emulate android

To emulate with live reload, run the commands with the extra flags –l and –c to start live reload and console logging. $ ionic emulate ios -l –c
$ ionic emulate android –l –c

Previewing on a mobile device $ ionic run ios -l –c
$ ionic run android -l -c


Now you have to build the Android project, which will generate a .apk file, and then you’ll install it onto the device. You need to locate your app inside the platforms/android/ant-build directory, and in it the filename that ends with –debug.apk: ionic build android
adb –d install platforms/android/ant-build/HelloCordova-debug.apk


What you need to know about AngularJS

                      Angular extends HTML with additional features that are made available through the many directives it provides or that you can create yourself.

Templates are HTML and may contain Angular directives or expressions. These templates are converted into a view that users interact with.

Controllers are used to hold the business logic of your application. They’re functions that can have any number of servers injected into them using Angular’s dependency injection system.

Scope is the glue that holds the controller and views together, and powers the two-way data binding in Angular. When data changes in the view or controller, the data is automatically synced to the other.

Filters are ways to transform data in a template without modifying the source model stored in the scope.
Directives are powerful, and you can create your own when you’re comfortable with Angular.

                                   AngularJS is a web application framework, and its popularity has made it one of the most-used JavaScript tools available today. Ionic is built on top of Angular, so it’s important to have a grasp of how it works. Instead of having to build an entire web application framework for Ionic, it uses Angular and extends it with a large number of interface components and other mobile-friendly features.
Share:

Popular Posts

Recent Posts

Unordered List

Pages