Android实战技巧之四十四:Hello,Native!
2015-11-03 10:47
417 查看
在Android上运行C程序对于做上层App的童鞋来说有些陌生,因为目前的Android应用开发怎么还是绕不过Java。
但对于底层驱动开发者,这就是家常便饭一样,因为Android是Linux分支,底层是C/C++的世界。
有时为了测试一些功能,我们也会编写直接运行在Android终端下的C程序。前提是有Android交叉编译器以及Android系统的root权限。
我的系统是64位的Ubuntu 14.04,所以我就下载了64位ndk(android-ndk-r10e-linux-x86_64.bin)。
此时,ndk就可以工作了。让我们将交叉编译工具变出来吧。
找到合适的路径,解压:
编译它:
跑起来:
将main_test拷到Android中运行:
如我们所愿,程序顺利的运行起来,跟在Linux系统中一样。下面我们来编译两个文件的程序。
shooter.c
shooter_tester.c
编译运行之:
shooter.c只是将上面的程序用rand和srand生成随机数。
只是编译的时候遇到了问题:
原来是随机数方法的头文件变成了stdlib,引入就可以了。
《Android问题集锦之四十五:undefined reference to ‘srand’》
编译运行结果如下:
但对于底层驱动开发者,这就是家常便饭一样,因为Android是Linux分支,底层是C/C++的世界。
有时为了测试一些功能,我们也会编写直接运行在Android终端下的C程序。前提是有Android交叉编译器以及Android系统的root权限。
交叉编译工具
ndk为我们开发native程序做了很多工作,下面我们将Android交叉编译工具从ndk中分离出来。我的系统是64位的Ubuntu 14.04,所以我就下载了64位ndk(android-ndk-r10e-linux-x86_64.bin)。
ndk$ chmod a+x android-ndk-r10e-linux-x86_64.bin ndk$ ./android-ndk-r10e-linux-x86_64.bin
此时,ndk就可以工作了。让我们将交叉编译工具变出来吧。
$ ./build/tools/make-standalone-toolchain.sh --platform=android-19 --toolchain=arm-linux-androideabi-4.9 Copying prebuilt binaries... Copying sysroot headers and libraries... Copying c++ runtime headers and libraries... Creating package file: /tmp/ndk-linc/arm-linux-androideabi-4.9.tar.bz2 Cleaning up... Done.
找到合适的路径,解压:
build-tools$ tar jxvf arm-linux-androideabi-4.9.tar.bz2 arm-linux-androideabi-4.9/ ...
hello,native
编译c文件main_test.c#include <stdio.h> int main() { printf("just a test,linc!hello, native!\n"); return 0; }
编译它:
$ ~/bin/build-tools/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gcc -o main_test main_test.c
跑起来:
将main_test拷到Android中运行:
$ adb push main_test /data/app 137 KB/s (6192 bytes in 0.043s) $ adb shell root@hammerhead:/ # cd data/app root@hammerhead:/data/app # ls main_test root@hammerhead:/data/app # ./main_test just a test,linc!hello, native!
如我们所愿,程序顺利的运行起来,跟在Linux系统中一样。下面我们来编译两个文件的程序。
shooter.c
#include "shooter.h" #include <stdio.h> void bubble_sort(int *array,int n) { int i,j,tmp; for(i=0;i<n-1;i++) { for(j=n-1;j>i;j--) { if(array[j-1]>array[j]) { tmp = array[j-1]; array[j-1]=array[j]; array[j]=tmp; } } } } int A(int a) { int n = 10; int i; int array[] = {54,12,346,5,23,67,234,324,45,98}; for(i=0;i<n;i++) { printf("%d, ",array[i]); } printf("\n"); bubble_sort(array,n); return array[0]; }
shooter_tester.c
#include <stdio.h> #include "shooter.h" int main() { int result = A(0); printf("A result: %d\n",result); return 0; }
编译运行之:
$ ~/bin/build-tools/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gcc -o test shooter_tester.c shooter.c $ adb push test /data/app/ 143 KB/s (6344 bytes in 0.043s) $ adb shell root@hammerhead:/ # cd data/app root@hammerhead:/data/app # ./test 54, 12, 346, 5, 23, 67, 234, 324, 45, 98, A result: 5
使用随机数
接下来尝试将《做一个动态链接库》中的代码在Android下测试,准备将此so移植到Android平台。shooter.c只是将上面的程序用rand和srand生成随机数。
#include "shooter.h" #include <time.h> #include <stdio.h> void bubble_sort(int *array,int n) { int i,j,tmp; for(i=0;i<n-1;i++) { for(j=n-1;j>i;j--) { if(array[j-1]>array[j]) { tmp = array[j-1]; array[j-1]=array[j]; array[j]=tmp; } } } } int A(int a) { int n = 10; int i; int array ; srand(time(NULL)); for(i=0;i<n;i++) { array[i] = rand()%100+1; printf("%d, ",array[i]); } printf("\n"); bubble_sort(array,n); return array[0]; }
只是编译的时候遇到了问题:
error: undefined reference to 'srand' error: undefined reference to 'rand'
原来是随机数方法的头文件变成了stdlib,引入就可以了。
《Android问题集锦之四十五:undefined reference to ‘srand’》
编译运行结果如下:
$ ~/bin/build-tools/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gcc -o test shooter_tester.c shooter.c $ adb shell root@hammerhead:/ # cd data/app root@hammerhead:/data/app # ./test 18, 95, 91, 55, 13, 37, 74, 85, 83, 66, A result: 13 root@hammerhead:/data/app # ./test 59, 100, 84, 32, 26, 46, 11, 50, 44, 83, A result: 11
尾声
现在,可以把Android当成Linux玩了。祝你愉快!相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories