android native 代码,【Android Native Code开发系列】一

只使用源码(如某些类)而不用重新编译的人可以略过此文

#######################################

配置android编译环境(for Ubuntu 10.04 64-bit)

#######################################

官方参考:http://source.android.com/source/initializing.html

网上资料:

Ubuntu 10.04下编译Android源码全过程

http://wenku.baidu.com/view/c130b16648d7c1c708a14551.html

Build android development platform in Ubuntu 10

http://wenku.baidu.com/view/042ea6fd700abb68a982fb2b.html

接着安装各种必需的软件包,如果有些包之前安装过了,可以不安装

***???*** 如果提示安装失败,可能要先安装Ubuntu重要更新???

if it failed due to dependency, try 'sudo aptitude install XXX'

instead.

1.  安装jdk

sudo add-apt-repository "deb

http://archive.canonical.com/ lucid partner"

sudo apt-get update

sudo apt-get install

sun-java6-jdk

2.  sudo apt-get install git-core

3.  sudo apt-get install gnupg

4.  sudo apt-get install flex

5.  sudo apt-get install bison

6.  sudo apt-get install gperf

7.  sudo apt-get install build-essential

8.  sudo apt-get install zip

9.  sudo apt-get install curl

10. sudo apt-get install zlib1g-dev  //

注意是数字b1g是数字1,不是字母l

11. sudo apt-get install libc6-dev

12. sudo apt-get install lib32ncurses5-dev

13. sudo apt-get install ia32-libs

14. sudo apt-get install x11proto-core-dev 15. sudo apt-get install libx11-dev 16. sudo apt-get install lib32readline5-dev

17. sudo apt-get install lib32z-dev

18. sudo apt-get install libgl1-mesa-dev

19. sudo apt-get install g++-multilib

20. sudo apt-get install mingw32

21. sudo apt-get install tofrodos

22. sudo apt-get install python-markdown

23. sudo apt-get install libxml2-utils

24. sudo apt-get install xsltproc

#######################################

下载android源码

#######################################

官方参考:http://source.android.com/source/downloading.html

如果下载全部源码,确保你有一个比较快而且稳定的网络连接。

1. 下载curl, git-core:

sudo apt-get install

git-core

sudo apt-get install

curl

2. mkdir ~/bin

PATH=~/bin:$PATH

3. 下载repo

curl

https://dl-ssl.google.com/dl/googlesource/git-repo/repo >

~/bin/repo

chmod a+x ~/bin/repo

4. 创建源码放置目录,如android,然后进入此目录准备执行后续命令

mkdir android

cd android

5. 初始化repo,准备下载源码,以下是下载代码仓库里的主线(master)代码

repo init -u

https://android.googlesource.com/platform/manifest 也可以下载某个分支(branch)项目代码,如2.3.3

revision 1

repo init -u

https://android.googlesource.com/platform/manifest

-b anroid-2.3.3_r1

6. 将源代码同步到本地,这个过程很长,主线代码我下完大概占了11GB空间(汗~~)

repo sync

#######################################

编译android源码 #######################################

官方:http://source.android.com/source/building.html

***NOTICE***这种编译不会编译SDK和kernel

与Android源代码编辑相关的一切操作介绍:

http://www.cnblogs.com/jerrychoi/archive/2010/09/06/1819563.html

1.  cd android

2.  初始化编译环境

source build/envsetup.sh 或 .

build/envsetup.sh

3.  选择编译模式

lunch full-eng //

除full-eng还有别的参数,见官方参考

4.  设置并行编译线程

make -j4 // 比如是一颗intel i5 4核

CPU,一个核跑一个线程,则1*4*1 = 4

# 编译android sdk

1.  cd android

2.  source build/envsetup.sh 或 .

build/envsetup.sh

3.  make PRODUCT-sdk-sdk //

应该也可以在sdk目录下运行mm,没试过...

# 运行自己编译的emulator

在上述编译过程后,在不退出当前shell的情况下,可直接运行emulator启动

以后直接启动,可参见:

cd

~/android/prebuilts/qemu-kernel/arm

emulator -sysdir

~/android/out/target/product/generic -kernel

kernel-qemu-armv7

不过这样启动是右边是没有键盘的,不知道为什么。。。

注意:

1。 系列六里也有一些编译相关的技巧

2。 编译过程中,如果出现需要类似缺少libxxx.so这样的出错信息,请到源码主目录编译此库: make libxxx

#######################################

编译自己的Native Code

#######################################

# 在有android源码的条件下,编译自己的native代码

1.

写好自己的c/c++工程代码,放在mymodule目录,并设置好同目录下的Android.mk

比如要编译一个动态库,代码为ZPService.h和ZPService.cpp,则这样配置:

----------------------------------------------

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=ZPService.cpp  // 源代码

LOCAL_SHARED_LIBRARIES:=libutils libbinder  // 依赖库 LOCAL_MODULE_TAGS:=optional

// 不要忘了这行

LOCAL_MODULE:=ZPService

//

生成库名,前面不需要加lib

LOCAL_PRELINK_MODULE:=false

// 编译成库,

若编译成可执行文件,则为

// include

$(BUILD_EXECUTABLE)

include

$(BUILD_SHARED_LIBRARY)

---------------------------------------------

2.  把源代码目录mymodule放在android/development/下

3.  (1)进入android根目录,运行

source

build/envsetup.sh

(2)或者,先运行source

build/envsetup.sh,再进入mymodule目录,运行

mm

4.  make libZPService

5.

生成的文件将放在android/out/target/product/generic/system下的bin

或lib目录,这要视你要编成库还是可执行文件而定

# 使用下载的ndk编译自己的native代码

1.  建立工程目录ndktest, 再建立子目录jni,

在jni下放置native代码和Android.mk, 如下所示:

../ndktest

`-- jni

|-- Android.mk

`-- test.cpp

2.  进入工程主目录下, 调用ndk-build编译

zp@zp-desktop:~/ndktest$

~/android-ndk-r7/ndk-build

Compile++ thumb

: zptest <= test.cpp

StaticLibrary

: libstdc++.a

Executable  : zptest

Install  : zptest

=> libs/armeabi/zptest

3.  如2所示, 生成的zptest位于ndktest/libs/armeabi目录.

编译后的目录结构如下:

../ndktest

|-- jni

|  |--

Android.mk

|  `--

test.cpp

|-- libs

|  `--

armeabi

|  `-- zptest

`-- obj

`-- local

`-- armeabi

|--

libstdc++.a

|--

objs

|

`-- zptest

|

|--

test.o

|

`--

test.o.d

`--

zptest

#######################################

Run,Debug自己编译的Native Code项目

#######################################

#

在模拟器上测试自己的代码

1.

先确保自己已经有android sdk,platform,

以及platform-tools;

要在shell直接运行emulator, android,

adb等命令,请把相应的路径添加到PATH;

如果用eclipse启动emulator,然后在shell执行adb push可能会出现"out

of

memory"错误,目前解决方法是也从shell启动emulator,若还出错,加-partition-size

xxx参数,xxx为容量

2.

启动emulator.

关于如何创建模拟器见“#官方android开发介绍”

zp@zp-desktop:~/ndktest$ emulator -avd avd2.3.3

-scale 0.5

-scale选项会调整模拟器的界面大小.

3.

将自己编译的模块拷贝到virtual device

zp@zp-desktop:~$ adb push

ndktest/libs/armeabi/zptest /data

163 KB/s (8476 bytes in 0.050s)

如果要将东西拷贝到system目录,要在adb

push之前执行:

adb remount

4.

在avd上执行自己的程序

zp@zp-desktop:~$ adb shell

# /data/zptest

hello Android!

也可以在avd界面上执行, 方法是打开应用程序库 > Dev Tools >

Terminal Emulator,

在出现的控制台输入'/data/zptest'

1. 准备工作

(1)因为要调用Android源代码的framework/base里的一些类,所以要确保有android相关源代码

(2)需要交叉编译器, 链接器等工具, 这个可以使用anroid源码里提供的工具,也可以使用单独下载的android

ndk

(3)可选: 如果在模拟器(AVD)上运行和调试, 还需要有编译好或者单独下载的android sdk及相应的组件等等,

关于各种组件需求,见

这里用的环境是android源码+单独下载的SDK(包括sdk toos, sdk platform

tools和platform组件)

2.

在android源码主目录/development子目录下建立工程目录, 我们的各个模块的代码都将放在这个目录的子目录下

cd  ~/android/development

mkdir zp_module

3. 建立service目录,里面放要做的native

service源码

ZPService.h

#ifndef ANDROID_ZPSERVICE_H

#define ANDROID_ZPSERVICE_H

#include

#include

#include

namespaceandroid

{

classZPService :publicBBinder

{

private:

//mutable Mutex m_Lock;

//int32_t m_NextConnId;

public:

staticintInstance();

ZPService();

virtual~ZPService();

virtualstatus_t onTransact(uint32_t,constParcel&, Parcel*, uint32_t);

};

}

#endif

ZPService.cpp

#include

#include

#include "ZPService.h"

namespaceandroid

{

//static struct sigaction oldact;

staticpthread_key_t sigbuskey;

intZPService::Instance()

{

LOGE("ZPService Instantiate\n");

intret = defaultServiceManager()->addService(

String16("zp.svc"),newZPService());

LOGE("ZPService ret = %d\n", ret);

returnret;

}

ZPService::ZPService()

{

LOGV("ZPService create\n");

//m_NextConnId = 1;

pthread_key_create(&sigbuskey,NULL);

}

ZPService::~ZPService()

{

pthread_key_delete(sigbuskey);

LOGV("ZPService destory\n");

}

status_t ZPService::onTransact(uint32_t code,

constParcel& data,

Parcel* reply,

uint32_t flags)

{

switch(code)

{

case0:

{

pid_t pid = data.readInt32();

intnum = data.readInt32();

num += 1000;

reply->writeInt32(num);

returnNO_ERROR;

} break;

default:

returnBBinder::onTransact(code, data, reply, flags);

}

}

}

Android.mk

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=ZPService.cpp

LOCAL_SHARED_LIBRARIES:=libutils libbinder

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=libZPService

LOCAL_PRELINK_MODULE:=false

include $(BUILD_SHARED_LIBRARY)

4.

建立svcserver目录,放置server源代码,

它主要用来将我们的service注册到系统.

zpserver.cpp

#include

#include

#include

#include

#include

#include

#include

#include

#include "../service/ZPService.h"

usingnamespaceandroid;

intmain(intarg,char** argv)

{

printf("server - ain() begin\n");

sp proc(ProcessState::self());

sp sm = defaultServiceManager();

//LOGI("ServiceManager: %p\n", sm.get());

printf("server - erviceManager: %p\n", sm.get());

intret = ZPService::Instance();

printf("server - ZPService::Instance return %d\n", ret);

ProcessState::self()->startThreadPool();

Android.mk

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=zpserver.cpp

LOCAL_SHARED_LIBRARIES:=libutils libbinder libZPService

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=zpserver

include $(BUILD_EXECUTABLE)

5.

创建svcclient目录, 放置client源代码,它用于调用service提供的服务.

它编译成一个动态库,供其他可执行程序调用, 也可以直接将它和第6步的调用程序直接编译成一个可执行文件

ZPClient.h

#ifndef ANDROID_ZPCLIENT_H

#define ANDROID_ZPCLIENT_H

namespaceandroid

{

classZPClient

{

public:

intsetN(intn);

private:

staticvoidgetZPService();

};

}

#endif

ZPClient.cpp

#include

#include

#include "ZPClient.h"

namespaceandroid

{

sp binder;

intZPClient::setN(intn)

{

getZPService();

Parcel data, reply;

data.writeInt32(getpid());

data.writeInt32(n);

LOGE("client - binder->transact()\n");

binder->transact(0, data, &reply);

intr = reply.readInt32();

returnr;

}

voidZPClient::getZPService()

{

sp sm = defaultServiceManager();

binder = sm->getService(String16("zp.svc"));

LOGE("client - etService: %p\n", sm.get());

if(binder == 0)

{

LOGW("ZPService not published, waiting...");

return;

}

}

}

Android.mk

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=ZPClient.cpp

LOCAL_SHARED_LIBRARIES:=libutils libbinder

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=libZPClient

LOCAL_PRELINK_MODULE:=false

include $(BUILD_SHARED_LIBRARY)

6. 创建svctest目录,

在里面开发一个测试程序,调用第5步的client库提供的接口,访问我们的service

test.cpp

#include

#include "../svcclient/ZPClient.h"

usingnamespaceandroid;

intmain(intargc,char** argv)

{

ZPClient client;

intret = client.setN(2012);

printf("setN return: %d\n", ret);

return0;

}

Android.mk

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=test.cpp

LOCAL_SHARED_LIBRARIES:=libZPClient

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=svctest

include $(BUILD_EXECUTABLE)

完成以上几步后,

我们的工程的目录结构如下(zp_module的父目录是development):

zp_module/

|-- Android.mk

|-- service

| |-- Android.mk

| |-- ZPService.cpp

| `-- ZPService.h

|-- svcclient

| |-- Android.mk

| |-- ZPClient.cpp

| `-- ZPClient.h

|-- svcserver

| |-- Android.mk

| `-- zpserver.cpp

`-- svctest

|-- Android.mk

`-- test.cpp

7. 编译所有项目

第一种方法, 进入android源码主目录,运行

source build/envsetup.sh 或 . build/envsetup.sh

然后进入development下你的源代码的各个子目录,

根据信赖性先后依次编译各个项目,比如进入development/zp_module/service, 运行 mm

第二种方法, 在zp_module下创建一个Android.mk文件, 输入以下内容:

include $(call all-subdir-makefiles

然后直接在zp_module目录下运行mm

8. 在模拟器里调试编译好的东西

(1) 打开emulator

emulator -avd avd4.0.3 -scale 0.6 -partition-size 256

(2) 打开adb, 等avd就绪后(用adb get-state查看状态,为device即准备好),

将编译好的库和可执行程序送入模拟器

zp@zp-desktop:~$ adb remount

remount succeeded

zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPService.so /system/lib

210 KB/s (10216 bytes in 0.047s)

zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPClient.so /system/lib

122 KB/s (5516 bytes in 0.044s)

zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/zpserver /data

124 KB/s (5572 bytes in 0.043s)

zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/svctest /data

121 KB/s (5568 bytes in 0.044s)

(3) 进入模拟器shell,先后运行zpserver和svctest

zp@zp-desktop:~$ adb shell

# /data/zpserver

server - ain() begin

server - erviceManager: 0xaa88

server - ZPService::Instance return 0

zp@zp-desktop:~$ adb shell

# /data/svctest

setN return: 3012

#

证明一切正确.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值