Android实战技巧之四十四:Hello,Native!

在Android上运行C程序对于做上层App的童鞋来说有些陌生,因为目前的Android应用开发怎么还是绕不过Java。

但对于底层驱动开发者,这就是家常便饭一样,因为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[n];

    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玩了。祝你愉快!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-28 14:51:10

Android实战技巧之四十四:Hello,Native!的相关文章

Android实战技巧之四十九:Usb通信之USB Host

零 USB背景知识 USB是一种数据通信方式,也是一种数据总线,而且是最复杂的总线之一. 硬件上,它是用插头连接.一边是公头(plug),一边是母头(receptacle).例如,PC上的插座就是母头,USB设备使用公头与PC连接. 目前USB硬件接口分三种,普通PC上使用的叫Type:原来诺基亚功能机时代的接口为Mini USB:目前Android手机使用的Micro USB. Host USB是由Host端控制整个总线的数据传输的.单个USB总线上,只能有一个Host. OTG On The

【转】Android实战技巧之四十九:Usb通信之USB Host

零 USB背景知识 USB是一种数据通信方式,也是一种数据总线,而且是最复杂的总线之一. 硬件上,它是用插头连接.一边是公头(plug),一边是母头(receptacle).例如,PC上的插座就是母头,USB设备使用公头与PC连接. 目前USB硬件接口分三种,普通PC上使用的叫Type:原来诺基亚功能机时代的接口为Mini USB:目前Android手机使用的Micro USB. Host USB是由Host端控制整个总线的数据传输的.单个USB总线上,只能有一个Host. OTG On The

Android实战技巧之四十:Android5.1.1源代码编译与烧写

购买Nexus手机的朋友大多是为了自己修改系统玩,再加上其较高的性价比,在开发者中还是广受欢迎的.我的5太子被我升级到了6.0预览版,玩的正嗨,舍不得换回到5.1时代了.不过鉴于距6.0源码发布还有段日子,5.1的源码编译与烧写仍是主流,下面就记录了整个过程(持续了很长时间,我们要有耐心). 搭建开发环境 系统推荐Ubuntu 14.04 1.openjdk is needed $ sudo apt-get update $ sudo apt-get install openjdk-7-jdk

Android实战技巧之十四:混淆与反编译

混淆 Android Studio: 只需在build.gradle(Module:app)中的buildTypes中增加release的编译选项即可,如下: buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } 这个proguard-android.txt是sdk中groguard默认的文件,

Android实战技巧之四十三:终止一个线程引起的

这是一道老牌面试题.通常面试官会问你对Java线程的了解,然后再问此问题. 从理论到实践,这是一条好路子. 线程是操作系统实现多任务的一种方式,可以理解为线程是一个任务的执行单元.比如Android系统中每个App都会有自己的主线程,同时还可以创建worker thread"并行"为我们工作. Java中创建新线程的方法 Java对线程(Thread)提供了语言级的支持(依托虚拟机吧).java.lang包下有Thread类和Runnable接口,都可以替你完成创建新线程的工作. 1.

Android实战技巧之三十五:了解native activity

1.native activity的意义 很多人觉得Android的Fwk提供的支持足够好了,既然Google不推荐用Ndk开发为什么又放宽Ndk的限制而推出可以无Java开发Android App呢?我的理解是不同的技术实现会有其适合的场景. Ndk的适用场景官方给出三点:1.平台间的App移植 2.复用现有库 3.对软件性能要求较高的场合比如游戏等.那么native activity在十分适合游戏领域,比如cocos-2dx对其的使用. 2.初步了解native activity 借助SDK

Android实战技巧之三十:人脸检测-静态

最近微软的how-old.net把人脸识别技术又大大的火了一把.通过大数据和复杂的算法,能够神奇的预测出照片中人物的性别和年龄.虽然错误率也不低,但是大家都抱着玩一玩乐一乐的心态把照片传上去让机器来鉴定一下自己的颜龄. 人脸识别算法是高深复杂的,面对着计算机视觉的种种数学公式,我就已经投降了.先来简单的玩玩人脸检测吧.Android早已提供了FaceDetector类,今天就来看看如何使用这个类人脸检测吧. 流程: 1.打开文件夹选择照片 2.将照片加载到bitmap中并缩放到设置的宽高 3.用

Android实战技巧之十:获得屏幕物理尺寸、密度及分辨率

大家帮忙喽! 博主参加2014博客之星活动,大家帮忙投票啦!猛击这里! 通过程序去了解硬件情况是一件十分有意思的事情.很早我就研究在WM6.5上获得屏幕物理尺寸,但一直没有成功.后来又想要在Android上有所突破,不过在今天之前得到的尺寸都不准确.虽然很多人认为没必要这么较真,因为貌似很多情况下用不到.不过我就当这是一件很有挑战性的事,一定要做到.对,就是这么任性. 源码中android.view包下的Display类提供了很多方法供程序员获得显示相关的信息,通过此类让我们开启了解设备屏幕之旅

Android实战技巧之三十六:Makefile快速入门

目标 通过一篇文章的介绍达到能够编写简单Makefile以及能够看懂普通的Makefile之目的. make简介 make是一个老牌的构建(build)工具,1970年问世以来已经度过了45年的时光而魅力不减,这在技术发展日新月异的今天是不可思议的.make在大型的软件项目中发挥着巨大作用.我是在学习Linux kernel时才第一次接触它,Android系统也是用make和python等脚本一起构建系统,所以掌握make知识是你迈进这些系统的第一道坎.你一定要给予make足够的重视,不要以为掌