(ZT) Using the Android NDK
2010-05-03 17:08
260 查看
http://fixnum.org/blog/2010/android_ndk/
A
few months ago I was looking to replace my Nokia E61 because the
battery was getting pretty unreliable. I ended up buying a T-Mobile G1
(or HTC Dream, whichever you prefer), because they were cheap at that
time, due to the then-recent release of the HTC Magic. Ironically, the
G1’s battery life is even worse than the Nokia with a near-dead
battery, but that's not the point. The point is I had a mobile phone
with an open operating system and a toolkit for Linux.
If you’ve used Android, you’ll know that while performance is OK, it
does tend to choke from time to time. This ‘choking’ is attributed to
the garbage collection of the Dalvik virtual machine. While this is
acceptable (but still quite annoying) for normal applications, it is a
dealbreaker for highly interactive applications such as games. Google
is not oblivious to this problem, and has released an NDK, or native
development kit, to complement their Java-based SDK. This allows
developers to write performance critical parts of their application in
C or C++, and use that from Java using something called JNI.
I wanted to try this out, but I failed to find any up-to-date
tutorial on the subject. After quite a bit of trying, I did get it
working though. I thought I’d share my experience with the world, so if
anyone else wanted to get started with the Android NDK, they’d have a
smoother start.
I write my code without Eclipse and the Android plugin for it, but
I’ll be explaining things for both command-line junkies like myself and
Eclipse users, like the majority of Android developers. I’ve tested the
Eclipse instructions on Windows, but it should work fine on Mac and
Linux as well. The Command line instructions will only work on Mac or
Linux, or on Windows if you use Cygwin.
means extracting it somewhere you can easily reach from the command
line or terminal.
would be through the "New Project" wizard. For command line users,
you’d run something like:
[/code]
Nothing new so far if you’ve build normal Android applications before.
directory of your NDK’s install path. Since Eclipse is most comfortable with handling your code in the
directory, I recommend you make a symbolic link. Even if you don’t use
Eclipse, you’ll probably want to put your code somewhere other than the
NDK install path.
First you’ll have to create a directory to hold your project and makefiles under the
directory. Call it anything you like, I’ll be referring to it as “the application folder” from here on in. I’m calling it
for this tutorial. Once you've done that, you need to create a symbolic link named
inside
this directory pointing to your Android project’s directory. On a Linux
or Mac system, type the following into your terminal while in the
application folder:
[/code]
On Windows, you can do the same by using the
command:
[/code]
You should also create a
directory in
:
[/code]
.
[/code]
would be embarassing not to combine them. If you’re using Eclipse,
building is most likely done automatically for you. To compile your
Java code from the command line, move into your project folder and type
[/code]
You should now have a nice set of Java .class files in the
directory of your project. Move your terminal over to
, and generate header files for your native method calls like this:
[/code]
This should get you a header file called
. Move this over to the
directory created earlier:
[/code]
directory, implementing the header created earlier. I’ve named it
, and it looks like this:
[/code]
The details here are about JNI, not the Android NDK, so if you have
any troubles here, look for a JNI tutorial. I don't know much about JNI
myself.
it. You only need to edit the obvious names here, not write your own
rules. For native Android extions, you'll need two makefiles.
The first should be in the application directory, which I named
earlier, and the file should be called
. It looks like this:
[/code]
The second should be create in the
folder with your C source code and header files, be called
and look somewhate like this:
[/code]
That’s all you need to do. The NDK’s main makefile will take care of the rest.
Android NDK’s install path. This should be two directories below the
application directory, and run:
[/code]
Obviously, you’ll need to replace the
with whatever you named your application directory earlier. Output should look something like this:
[/code]
include your native library. If you’re using Eclipse, simply press run.
For command line user, you need to run another
task in the
folder:
[/code]
If you want to install the application from the command line as well, run
too. To see what messages are being logged, run
.
Now you can run the application, and in the logs, you should read a wonderful message like this:
[/code]
That’s it. Feel free to leave a comment if you have any questions or run into problems.
Using the Android NDK
Written on Saturday 23/01/2010 at 09:24A
few months ago I was looking to replace my Nokia E61 because the
battery was getting pretty unreliable. I ended up buying a T-Mobile G1
(or HTC Dream, whichever you prefer), because they were cheap at that
time, due to the then-recent release of the HTC Magic. Ironically, the
G1’s battery life is even worse than the Nokia with a near-dead
battery, but that's not the point. The point is I had a mobile phone
with an open operating system and a toolkit for Linux.
If you’ve used Android, you’ll know that while performance is OK, it
does tend to choke from time to time. This ‘choking’ is attributed to
the garbage collection of the Dalvik virtual machine. While this is
acceptable (but still quite annoying) for normal applications, it is a
dealbreaker for highly interactive applications such as games. Google
is not oblivious to this problem, and has released an NDK, or native
development kit, to complement their Java-based SDK. This allows
developers to write performance critical parts of their application in
C or C++, and use that from Java using something called JNI.
I wanted to try this out, but I failed to find any up-to-date
tutorial on the subject. After quite a bit of trying, I did get it
working though. I thought I’d share my experience with the world, so if
anyone else wanted to get started with the Android NDK, they’d have a
smoother start.
I write my code without Eclipse and the Android plugin for it, but
I’ll be explaining things for both command-line junkies like myself and
Eclipse users, like the majority of Android developers. I’ve tested the
Eclipse instructions on Windows, but it should work fine on Mac and
Linux as well. The Command line instructions will only work on Mac or
Linux, or on Windows if you use Cygwin.
Step 0: Download and install the SDK and NDK
I’m assuming you’ve already done this. Installing the NDK simplymeans extracting it somewhere you can easily reach from the command
line or terminal.
Step 1: Create a project
Create a project like you normally would. For Eclipse users, thiswould be through the "New Project" wizard. For command line users,
you’d run something like:
android create project --target 2 --name Demo --path project_folder --activity DemoActivity --package your.pkg.name
[/code]
Nothing new so far if you’ve build normal Android applications before.
Step 2: Make your project visible to the NDK
The development kit requires your application to be in theapps
directory of your NDK’s install path. Since Eclipse is most comfortable with handling your code in the
workspace
directory, I recommend you make a symbolic link. Even if you don’t use
Eclipse, you’ll probably want to put your code somewhere other than the
NDK install path.
First you’ll have to create a directory to hold your project and makefiles under the
apps
directory. Call it anything you like, I’ll be referring to it as “the application folder” from here on in. I’m calling it
demo_app
for this tutorial. Once you've done that, you need to create a symbolic link named
project
inside
this directory pointing to your Android project’s directory. On a Linux
or Mac system, type the following into your terminal while in the
application folder:
ln -s /full/path/to/android/project project
[/code]
On Windows, you can do the same by using the
linkd
command:
linkd project full/path/to/android/project
[/code]
You should also create a
jni
directory in
project
:
mkdir project/jni
[/code]
Step 3: Add native references to your Java code
You need to add some references to your JNI code in the generate Java code. I’ve highlighted the required changes toDemoActivity.java
.
package your.pkg.name; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class DemoActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); Log.i("---DEMO---", "Return value from native lib: " + getString()); } public native String getString(); static { System.loadLibrary("native_lib_name"); } }
[/code]
Step 4: Build Java code and generate header files
Ok, so this really is more like two steps, but they’re so simple itwould be embarassing not to combine them. If you’re using Eclipse,
building is most likely done automatically for you. To compile your
Java code from the command line, move into your project folder and type
ant compile
[/code]
You should now have a nice set of Java .class files in the
bin
directory of your project. Move your terminal over to
bin/classes
, and generate header files for your native method calls like this:
javah -jni your.pkg.name.DemoActivity
[/code]
This should get you a header file called
your_pkg_name_DemoActivity.h
. Move this over to the
jni
directory created earlier:
mv your_pkg_name_DemoActivity.h ../../jni
[/code]
Step 5: Implement the header files
Next, you'll need to create a C file in thejni
directory, implementing the header created earlier. I’ve named it
DemoActivity.c
, and it looks like this:
#include "your_pkg_name_DemoActivity.h" JNIEXPORT jstring JNICALL Java_your_pkg_name_DemoActivity_getString (JNIEnv * env, jobject obj) { return (*env)->NewStringUTF(env, "Complex string calculated in native code"); }
[/code]
The details here are about JNI, not the Android NDK, so if you have
any troubles here, look for a JNI tutorial. I don't know much about JNI
myself.
Step 6: Create makefiles
Now, I know makefiles can be somewhat scary, but don't worry aboutit. You only need to edit the obvious names here, not write your own
rules. For native Android extions, you'll need two makefiles.
The first should be in the application directory, which I named
demo_app
earlier, and the file should be called
Application.mk
. It looks like this:
APP_PROJECT_PATH := $(call my-dir)/project APP_MODULES := native_lib_name
[/code]
The second should be create in the
jni
folder with your C source code and header files, be called
Android.mk
and look somewhate like this:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := native_lib_name LOCAL_SRC_FILES := DemoActivity.c include $(BUILD_SHARED_LIBRARY)
[/code]
That’s all you need to do. The NDK’s main makefile will take care of the rest.
Step 7: Build the native code
To build the native code, move your terminal to the root of theAndroid NDK’s install path. This should be two directories below the
application directory, and run:
make APP=demo_app
[/code]
Obviously, you’ll need to replace the
demo_app
with whatever you named your application directory earlier. Output should look something like this:
Android NDK: Building for application 'demo_app' Compile thumb : native_lib_name <= apps/demo_app/project/jni/DemoActivity.c SharedLibrary : libnative_lib_name.so Install : libnative_lib_name.so => apps/demo_app/project/libs/armeabi
[/code]
Step 8: Build the Android application
You now need to rebuild and repackage the entire application toinclude your native library. If you’re using Eclipse, simply press run.
For command line user, you need to run another
ant
task in the
project
folder:
ant debug
[/code]
If you want to install the application from the command line as well, run
ant install
too. To see what messages are being logged, run
adb logcat
.
Now you can run the application, and in the logs, you should read a wonderful message like this:
I/---DEMO---( 198): Return value from native lib: Complex string calculated in native code
[/code]
That’s it. Feel free to leave a comment if you have any questions or run into problems.
相关文章推荐
- Obfuscating Android Applications using O-LLVM and the NDK
- Android C native development using the NDK under Windows
- Porting of cURL to Android OS using NDK (from The Software Rogue)
- Android-Android studio 出现 Error: NDK integration is deprecated in the current plugin. 问题解决
- 《Pro Android C++ with the NDK》 第三章阅读笔记
- No instrumentation runner found for the launch, using android.test.
- 使用apt导入时报警告:Warning:Using incompatible plugins for the annotation processing: android-apt. This may
- Using the Android Parcel
- Warning: No instrumentation runner found for the launch, using android.test.InstrumentationTestRunne
- Android studio两种工程目录视图对比--Using the Android Project View
- Using the Android Application class to persist data
- “The Android NDK cannot be installed into a path with spaces”的解决方法
- Error:The project is using an unsupported version of the Android Gradle plug-in (0.8.3). The recomme
- Android 自定义控件build时提示Custom view * is not using the 2- or 3-argument View constructors; XML attribut
- Android Using the Cursor
- Steps for creating android applications using NDK and ARM assembly language
- glob.h and glob.c for the Android NDK
- Error:No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi
- Android Material Design-Using the Material Theme(使用Material主题)-(二)
- Warning: No instrumentation runner found for the launch, using android.test.InstrumentationTestRunner