谨以此文纪念一个多月的努力。
Android的应用平台与Linux的内核之间有那么几层,1.c++框架2.JAVA 框架。一个月前,突然发现Android下的录音无法使用,不管是自带的程序还是网上下载的程序都无法使用,调试内核发现,参数传递错误,开始以为是Linux的内核出错,使用Linux下的aplay可以录音而录音软件不可以使用,使用录音软件时发现传递的stream为0,而不是1.所以打开的设备是playback而不是capture设备,为了这一步就花了一个星期的时间去查看Linux的源码。其后准备去看Linux kernel与应用程序间的交互,发现者中间还有opencore层。一堆的JAVA以及C++,凭我那浅陋的C语言是很难理解的。不得不放弃,然后了解到还有ndk这个东东,就动心了,因为Linux下的aplay是可以使用的,我把它做成一个so库留给上层调用就行了。化了两三天把eclipse sdk ndk 等等windows下的android 开发环境装好后,就开始了ndk的的so库之旅。功夫不负有心人,so库的模型做好了,下面就等着填东西了。
下面咱从android 开发环境安装开始说吧。
1. eclipse安装
下一个eclipse-java-helios-SR1-win32.zip 解压即可,不过这个东西需要安装java开发环境,java安装也很简单下载一个jre-6u23-windows-i586.exe 以及jdk-6u23-windows-i586.exe点击安装就可以了。有时候在打开eclipse时会提示一些错误,其实有可能是没有jre文件夹,copy java安装文件下jdk文件中jre文件夹复制到eclipse的文件夹下即可。
2. sdk 安装
下载一个android-sdk_r08-windows.zip解压即可。一般情况下还需要将其路径加入环境变量中,不加也可以。区别是如果加了,在eclipse中新建的android的虚拟器会放在该文件夹下,名字为.android,如果不加的话,会在C:/Documents and Settings/用户名 下,有些错误的原因就是用户名为汉字。
3. 添加PATH
我的电脑->属性->高级->环境变量->新建
变量名 JRE_HOME 变量值 C:/Program Files/Java/jre6
变量名 JAVA_JRE_HOME变量值 C:/Program/Files/Java/jdk1.6.0_13/jre
变量名 JAVA_HOME 变量值 C:/Program Files/Java/jdk1.6.0_23
变量名 CLASSPATH
变量值
.;%JAVA_HOME%/lib;%JAVA_HOME%/lib/tools.jar;%JAVA_HOME%/lib/dt.jar;%JRE_HOME%/lib;%JRE_HOME%/lib/rt.jar;%JAVA_JRE_HOME%/lib;%JAVA_JRE_HOME%/lib/rt.jar
变量名 Android_SDK_HOME 变量值D:/Android/source/android-sdk-windows
4. eclipse中的安装adt插件
打开eclipse后 help->install new software->add name任意,location中为 http://dl-ssl.google.com/android/eclipse,然后就一路next就ok了。安装后在主界面上file->new->project中有Android选项就ok了。不过还需要配置sdk为位置,在windows->preferences中的android一项中点击browse选择sdk放置的位置就可以了。
5. ndk安装
下载cygwinsetup.zip 和android-ndk-r5-windows.zip注意了android-ndk-1.6_r1-windows.zip下没有ndk-build,这个版本的我不知道怎么编译就换了一个高版本的。安装cygwinsetup,一路next后选择一个比较近的网站下载,在选择下载安装哪些软件时,全部选择Install就行了,反正时间不是太长(我下了一个晚上,嘿嘿!!)。然后就ok了,在桌面上会有一个cygwin的图标,打开后,类似一个终端。在这里需要设置ndk的路径,因为你以后会用很多次的。采用vi /etc/skel/.bashrc 在最后添加
NDK=/cygdrive/xxx/xxx
PATH=$PATH:$NDK
export NDK
退出,然后source /etc/skel/.bashrc 就可以了,你在命令行中输入
$NDK 应该会打开ndk所在的文件夹
6. adb安装
下载一个adb压缩文件,解压,把里面的两个文件copy到windows/system32下即可。在start->运行 cd c:/ windows/system32然后就可以使用adb 了。
7. 如何新建一个Android工程
新建一个android 的工程需要新建一个avd,主界面windws->Android SDK and AVD Manager –>new.
Name :avdtest
Target :Android 2.1
SD Card :400 Mb
Creat avd后。会在主界面中罗列出可用的avd了。
8. 新建一个android 的工程
File->new->project->Android->Android project 然后next,
Project name :随意
Build Target :选择虚拟机
Application name :随意
下面的几个那么都随意。注意Min sdk version 可以是1~9值,如果是Android 2.1的话,最高为7. Finish 就可以了。然后在主界面上点击Run就可以运行了。
9. Adb使用
1. 在进入system32后运行adb shell 可以进入正在运行的Android的系统终端。
2. Adb push 向Android系统中写入东西,一般第一次会提示Read-Only filesytem ,这就需要adb shell进入终端后,输入
mount –o remount /dev/block/mtdblock /system就可以了。
如果出现out–memory
则cmd中输入 emulator –avd avdname –partition-size 128,注意了,如果提示说没有emulator的命令,则需要设置环境变量,上面偷懒了,下面就不行了。
3. adb pull 可以将android系统内的东西输出。
如adb pull /data/app/com.examples.apk d:/android/apk
10. so库的创建
1. 在刚才新建的工程下,新建一个folder,name 为jni,在jni下新建两个文件,一个是Android.mk,一个是hello.c。
2. 在Android.mk中输入
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
LOCAL_LDLIBS := -ldl -llog #添加系统的so文件
LOCAL_LDLIBS += -L./ -lasound #添加本地的so文件 -L为so库的路径,这个在调用别人的so库,并且有头文件的情况下加快开发速度。
include $(BUILD_SHARED_LIBRARY)
3. 在hello.c中添加
#include
#include
#include
#include
jint Java_com_hello_hello_hello(JNIEnv* env,jobject this)
{
return 12;
}
注意:以上的函数命名为com.hello为包名即是新建android工程时,package name,
第二个hello为application name ,这个必须要和工程相互对于。第三个hello就是你打算在java中调用的函数名。修改src下的hello.java
package com.hello;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class hello extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
TextView tv = new TextView(this);
tv.setText("hello 调用是否成功:" + hello());
setContentView(tv);
}
public native int hello();
static {
System.loadLibrary("hello");
}
}
如果以上都没有错的话,点击run就可以了,然后再android虚拟机上会出现” hello 调用是否成功: 12”。Ok!有个小窍门,一般人不告诉他就是,没有对文件改动时,注意点击refrresh,不行的话注意,点击主界面上的project->clean