zoukankan      html  css  js  c++  java
  • android平台中编写jni模块的方法(1)

    本文主要来记录一下偶对android平台下面jni技术的研究心得体会,一来是备忘,二来也为后来者节省一些独自摸索的时间。

    一直在忙 着project方面的事情,听到一个朋友提起说偶的blog很久没有更新了。所以今天抽一些时间上来写点东西。没办法,随着手机行业的竞争日趋白热化, 加上google,apple,palm之流的公司搅局,在手机领域的从业者的空闲时间越来越少,竞争也日趋白热化。

    闲话少叙,开始进入正题:
    1、介绍一下命令行开发的方法
    由于用c/c++习惯了,所以对eclipse的使用很是不习惯,还是决定用命令行(makefile类似)的方式进行编译、开发(偶个人比较痴迷emacs)。
    如果是java平台的话自然要选用ant了,关于linux下面android sdk的安装以及环境变量的设置在此偶就不再赘述了,

    偶选用的工作环境如下:
    软件环境:android-sdk-linux_x86_1.5_r1,jdk 1.6.0_12,slackware 12.1G,
    硬件环境:lenvo sl400(办公本本),android g1(已被破解,并刷入cupcake 1.5的版本)

    (1)创建项目
    wayne@wayne:~/works/workspace$android create project --target 2 --package com.twm --activity JniTest --path /home/wayne/works/workspace/JniTest

    这里面的android是1.5版本的sdk提供的一个脚本工 具,需要注意的是参数--target(谢天谢地,google总算可以在一个sdk里面同时支持1.1版本和1.5版本的android软件开发 了),--target取值为1的时候代表生成的项目是android 1.1版本的工程,--target取值为2的时候代表生成的项目是android 1.5版本的工程,在上面的命令行中,我们创建的是取值为2的for 1.5版本的android应用程序项目。

    (2)编译项目
    cd JniTest
    ant debug
    接着会看到如下的输出:
    Buildfile: build.xml
        [setup] Project Target: Android 1.5
        [setup] API level: 3

    dirs:
         [echo] Creating output directories if needed...

    resource-src:
         [echo] Generating R.java / Manifest.java from the resources...

    aidl:
         [echo] Compiling aidl files into Java classes...

    compile:
        [javac] Compiling 1 source file to /home/wayne/works/workspace/JniTest/bin/classes

    dex:
         [echo] Converting compiled files and external libraries into bin/classes.dex...

    package-resources:
         [echo] Packaging resources
     [aaptexec] Creating full resource package...

    debug:
    [apkbuilder] Creating .JniTest-debug.apk and signing it with a debug key...
    [apkbuilder] Using keystore: /home/wayne/.android/debug.keystore

    BUILD SUCCESSFUL
    Total time: 6 seconds

    ok,如果看到了类似偶的画面,就代表你的命令行编译环境编译没有问题。
    下面就是验证一下了:
    cd bin
    ls
    如果看到了JniTest-debug.apk,呵呵,代表你的安装包已经生成了(注意这里是debug版本的安装包,此时你可以启动模拟器,然后用adb install,然后到模拟器上看看hello world的效果。汗,是不是太容易了?!)

    (3)生成release版本的安装包
    刚刚是生成了debug版本的安装包,那么我们要生成release版本的该如何做呢?很容易,回到JniTest目录,运行如下命令:
    ant release
    会看到如下输出:
    Buildfile: build.xml
        [setup] Project Target: Android 1.5
        [setup] API level: 3

    dirs:
         [echo] Creating output directories if needed...

    resource-src:
         [echo] Generating R.java / Manifest.java from the resources...

    aidl:
         [echo] Compiling aidl files into Java classes...

    compile:
        [javac] Compiling 1 source file to /home/wayne/works/workspace/JniTest/bin/classes

    dex:
         [echo] Converting compiled files and external libraries into bin/classes.dex...

    package-resources:
         [echo] Packaging resources
     [aaptexec] Creating full resource package...

    release:
    [apkbuilder] Creating .JniTest-unsigned.apk for release...
         [echo] All generated packages need to be signed with jarsigner before they are published.

    BUILD SUCCESSFUL
    Total time: 4 seconds

    ok,这个时候请注意,这里面有这样一句:
    [apkbuilder] Creating .JniTest-unsigned.apk for release...
     [echo] All generated packages need to be signed with jarsigner before they are published.
    看来是生成了一个叫做JniTest-unsigned.apk的发布版安装包,而且很“贴心”地告诉我们这个包需要做jarsigner的签名(NND,都怪nokia带了一个坏头,现在给手机写个稍微有点用处的程序无论什么平台都要签名。。。很不爽)

    (4)为release版本的apk制作签名
    keytool -genkey -v -keystore waynechen.keystore -alias wayne -keyalg RSA -validity 10000
    这里是用了linux的一个工具来生成一个用于标明身份的key(anyway,偶的测试手机自然是被破解和刷过多次的,但是有一点可以肯定,不签名即使是破解过的android G1也不能安装那个unsigned的apk)。
    上述命令运行完毕后,会生成一个叫做waynechen.keystore的签名文件,为了下一步jarsinger做准备。

    (5)为unsigned的apk安装包签名
    这个jarsigner不是android sdk提供的工具,而是jdk里面提供的工具,因此,找不到这个工具的朋友可以查看jdk的bin路径是否已经加入到当前的path里面。
    jarsigner -verbose -keystore waynechen.keystore JniTest-unsigned.apk wayne
    签过名以后的文件仍然叫做JniTest-unsigned.apk,不过此时的apk文件可是已经签过名的了,可以在真机上面安装。

    好了,到此为止已经聒噪了一大堆通过命令行编译android代码的方法了,使用eclipse ide做开发的朋友可以直接跳过上述步骤(靠,现在才说,拍死你。。。)

    2.jni的基本工作原理
    (1)java的本质
    想 搞明白jni的本质,还要从java的本质说起。从本质上来说,java这门语言就是一门脚本语言(这是偶的个人理解,希望java大侠们不要用板砖拍 我),它的运行完全依赖于脚本引擎对java的代码进行解释和执行(当然了,现代的java已经先进许多,可以从源代码编译成.class之类的中间格式 的二进制文件,这种处理会大大地加快java脚本的运行速度,但是基本的执行方式仍然不变,由脚本引擎(我们称之为JVM)来执行,与python、 perl之类的纯脚本相比,它只是把脚本变成了二进制格式而已。另外就是java本身对面向对象的概念支持得很好,拥有完善的功能库可供调用,把这个脚本 引擎移植到所有平台上,那么这个脚本自然就实现所谓的“跨平台”了)。绝大多数的脚本引擎都支持一个很显著的特性,就是可以通过c/c++编写模块,在脚 本中调用这些模块,以此来类比java,也是一样的,java一定要提供一种在脚本中调用c/c++编写的模块的机制,才能称得上是一个相对完善的脚本引 擎。

    (2)android中的java
    android平台从本质上是 由arm-linux操作系统 和一个叫做dalvik的java虚拟机组成的。所有在android模拟器上面看到的那些华丽的界面,都是用java语言编写的(参见android平 台源代码的frameworks/base目录)。目前看来dalvik只是提供了一个标准的支持jni调用的java虚拟机环境。android平台中 所有的硬件相关的操作均是采用jni技术进行了封装,由java去调用jni模块,而jni模块使用c/c++调用android本身的arm- linux底层驱动。

    例如,frameworks/base/libs/ui目录下面有一个叫做“EGLDisplaySurface.cpp”的文件,里面的:
    status_t EGLDisplaySurface::mapFrameBuffer()函数中,就有直接对android的arm-linux中的framebuffer的初始化代码。

    这也更加印证了,android其实是依靠java+jni建立起来的王国。hoho,如此一来,就凸显出jni在android开发中的重要性(当然,一些简单的小程序是完全可以只用java就搞定的).

    本想写一篇文章就记录下来jni的编写和调试方法的。。。
    结果一不小心跑题了,把一些周边的入门性的知识介绍了那么多,只好下一篇再继续说了。

  • 相关阅读:
    3-1
    3-2
    习题二 8
    习题二 3
    习题二 5
    习题二 4
    习题二 6
    实验三-2未完成
    实验三
    心得
  • 原文地址:https://www.cnblogs.com/xiaoxiaoboke/p/2348940.html
Copyright © 2011-2022 走看看