一、底层实现:

c文件:hardware/libhardware_legacy/power/power.c

以其中set_screen_state(int)函数为例

其Android.mk中添加:
    LOCAL_MODULE:= libpower 编译成lib
    LOCAL_SRC_FILES += power.c

hardware/libhardware_legacy/power/power.c

   1:  int
   2:  set_screen_state(int on) 
   3:  {
   4:      QEMU_FALLBACK(set_screen_state(on));
   5:   
   6:      LOGI("*** set_screen_state %d", on);
   7:   
   8:      initialize_fds();
   9:   
  10:      //LOGI("go_to_sleep eventTime=%lld now=%lld g_error=%s\n", eventTime,
  11:        //      systemTime(), strerror(g_error));
  12:   
  13:      if (g_error)
  14:          goto failure;
  15:   
  16:      char buf[32];
  17:      int len;
  18:      if(on)
  19:          len = snprintf(buf, sizeof(buf), "%s", on_state);
  20:      else
  21:          len = snprintf(buf, sizeof(buf), "%s", off_state);
  22:   
  23:      buf[sizeof(buf) - 1] = '\0';
  24:      len = write(g_fds[REQUEST_STATE], buf, len);
  25:      if(len < 0) {
  26:      failure:
  27:          LOGE("Failed setting last user activity: g_error=%d\n", g_error);
  28:      }
  29:      return 0;
  30:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

其头文件power.h中:

   1:  #if__cplusplus
   2:  extern "C" {               //注1
   3:  #endif
   4:  enum { 
   5:      PARTIAL_WAKE_LOCK = 1,  // the cpu stays on, but the screen is off
   6:      FULL_WAKE_LOCK = 2  // the screen is also on  
   7:  };
   8:    
   9:  // while you have a lock held, the device will stay on at least at the
  10:  // level you request. 
  11:  int acquire_wake_lock(int lock, const char* id);  
  12:  int release_wake_lock(const char* id);
  13:    
  14:  // true if you want the screen on, false if you want it off   
  15:  int set_screen_state(int on); 
  16:    
  17:  // set how long to stay awake after the last user activity in seconds 
  18:  int set_last_user_activity_timeout(int64_t delay);
  19:    
  20:    
  21:  #if __cplusplus   
  22:  } // extern "C"   
  23:  #endif    

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

注1:

注1:extern表示其他的类已经定义了这段代码里面的内容,这里只是做声明。
"C”表示的一种编译和连接规约,这里为下一步c++调用其做准备.
比如void foo(int,int);该函数被C编译器编译后在库中的名字为_foo,
而C++编译器则会产生像_foo_int_int之类的名字用来支持函数重载和类型安全连接。
由于编译后的名字不同,C++程序不能直接调用C函数。
因此C++提供了一个C连接交换指定符号extern“C”来解决这个问题而不是一种语言。
C表示这段代码可以是符合C语言的编译和连接规约的任何语言,如Fortran、assembler等。

二、cpp构成jni桥梁

一个CPP文件调用之,则需添加其头文件,比如frameworks/base/core/jni/android_os_Power.cpp.

   1:  #include "JNIHelp.h"
   2:  #include "jni.h"
   3:  #include "android_runtime/AndroidRuntime.h"
   4:  #include <hardware_legacy/power.h>
   5:  namespace android{
   6:  ....
   7:   
   8:      //定义函数:
   9:          static int setScreenState(JNIEnv *env, jobject clazz, jboolean on)
  10:          {
  11:              return set_screen_state(on);//以此实现cpp到c的调用
  12:          }
  13:          
  14:          static JNINativeMethod method_table[] = {//此处实现java对cpp的调用转化 注2
  15:              { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock },
  16:              { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock },
  17:              { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
  18:              { "setScreenState", "(Z)I", (void*)setScreenState },
  19:              { "shutdown", "()V", (void*)android_os_Power_shutdown },
  20:              { "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
  21:          };
  22:          int register_android_os_Power(JNIEnv *env)        //此处注册jni
  23:          {    //向VM(即AndroidRuntime)登记 gMethods[]表格所含的本地函数
  24:              return AndroidRuntime::registerNativeMethods(
  25:                  env, "android/os/Power",
  26:                  method_table, NELEM(method_table));
  27:          }
  28:  };
 注2:

typedef struct {
    const char* name;              //Java中函数的名字
    const char* signature;       //用字符串是描述了函数的参数和返回值       
    void*       fnPtr;             //函数指针,指向C函数
} JNINativeMethod;
其中比较难以理解的是第二个参数,例如
    "()V"
    "(II)V"
    "(Ljava/lang/String;Ljava/lang/String;)V"
    实际上这些字符是与函数的参数类型一一对应的。
    "()" 中的字符表示参数,后面的则代表返回值。例如"()V" 就表示void Func();
    "(II)V" 表示 void Func(int, int);
    具体的每一个字符的对应关系如下
    字符     Java类型     C类型
    V          void           void
    Z          jboolean    boolean
    I          jint        int
    J          jlong       long
    D          jdouble     double
    F          jfloat      float
    B          jbyte       byte
    C          jchar       char
    S          jshort      short
    数组则以"["开始,用两个字符表示
    [I       jintArray      int[]
    [F     jfloatArray    float[]
    [B     jbyteArray    byte[]
    [C    jcharArray    char[]
    [S    jshortArray   short[]
    [D    jdoubleArray double[]
    [J     jlongArray     long[]
    [Z    jbooleanArray boolean[]
    上面的都是基本类型。如果Java函数的参数是class,则以"L"开头,以";"结尾中间是用"/" 隔开的包及类名。而其对应的C函数名的参数则为jobject. 一个例外是String类,其对应的类为jstring
    Ljava/lang/String; String jstring
    Ljava/net/Socket; Socket jobject
    如果JAVA函数位于一个嵌入类,则用$作为类名间的分隔符。
    例如 "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z"

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

三、java的封装实现

frameworks/base/core/java/android/os/Power.java        //此处路径跟cpp中注册jni处的路径是一致的.待细研究是否有关系

   1:  package android.os;
   2:  public class Power
   3:  {
   4:          ...
   5:          public static native int setScreenState(boolean on);    //被native修饰的表示调用了非java语言的本地方法
   6:          ...
   7:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

四、java中对其调用

frameworks/base/services/java/com/android/server/PowerManagerService.java

import android.os.Power;
public class PowerManagerService extends IPowerManager.Stub
implements LocalPowerManager, Watchdog.Monitor {
...
int err = Power.setScreenState(on);
...
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

android的jni的更多相关文章

  1. Android 通过JNI实现守护进程,使得Service服务不被杀死

    来自: http://finalshares.com/read-7306 转载请注明出处: http://blog.csdn.net/yyh352091626/article/details/5054 ...

  2. android的JNI 、 NDK 学习!

    转载的! Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) ...

  3. Android 中JNI创建实例

    参考文档: http://blog.sina.com.cn/s/blog_a11f64590101924l.html http://www.cnblogs.com/hoys/archive/2010/ ...

  4. 【转】Android中JNI的使用方法

    Android中JNI的使用方法 首先看一下Android平台的框架图:(网上盗用) 可以看到Android上层的Application和ApplicationFramework都是使用Java编写, ...

  5. Android使用JNI(从java调用本地函数)

    当编写一个混合有本地C代码和Java的应用程序时,需要使用Java本地接口(JNI)作为连接桥梁.JNI作为一个软件层和API,允许使用本地代码调用Java对象的方法,同时也允许在Java方法中调用本 ...

  6. I.MX6 android BatteryService jni hacking

    /**************************************************************************** * I.MX6 android Batter ...

  7. Android中JNI编程的那些事儿(1)

    转:Android中JNI编程的那些事儿(1)http://mobile.51cto.com/android-267538.htm Android系统不允许一个纯粹使用C/C++的程序出现,它要求必须 ...

  8. 【转】Android与JNI(二) -- 不错

    原文网址:http://www.cnblogs.com/eddy-he/archive/2012/08/09/2629974.html 软件版本: ubuntu10.04 java version & ...

  9. (原)android的JNI中使用C++的类

    android的JNI代码中可以调用C++的类,但是不能直接调用,要加上一个类似于接口的java类,这个类内部调用C++的类.实际上和接口类直接调用C++中的函数差不多,只是稍微复杂了一点. 1. 写 ...

  10. [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so

    0:前言: 在第二篇中,我们主要介绍了丙方android公司利用乙方C++公司给的动态库,直接调用库中的方法,但是这样方式受限于: 乙方C++公司开发的动态库是否符合jni的规范,如果不规范,则不能直 ...

随机推荐

  1. WPF样式——多条件触发器

    希望创建多个条件都为真时才激发的触发器,就需要使用MultiTrigger提供的Condition集合 <Window x:Class="Styles.MultiTrigger&quo ...

  2. LeapMotion(2):追踪五指

    上一篇文章,我们实现了Leap Motion的简单测试.追踪其中一个手指并用红色圆形表示其在空间的位置. 这篇文章,我们来实现五指的追踪. 其实,能够实现一指的追踪,那么五指的追踪自然不成问题.但是, ...

  3. OpenNMS架构介绍

    一.OpenNMS简介 OpenNMS的开发基于TMN及FCAPS这两个模型. 电信管理网络(TMN)是由 ITU-T 推荐 M.3000于1985年提出作为一种应用于电信服务供应商所持有的运营支持系 ...

  4. IO流的异常处理

    在IO流的异常处理时应该注意以下几点: 1.在外边建立引用,在Try内进行初始化(FileWriter fw = null;) 2.文件的路径使用必须是双斜杠,转义(fw = new FileWrit ...

  5. Linux流量监控工具 - iftop (最全面的iftop教程)

    在类Unix系统中可以使用top查看系统资源.进程.内存占用等信息.查看网络状态可以使用netstat.nmap等工具.若要查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop. 一.if ...

  6. 关于Resources.LoadAssetAtPath

    返回的是Object, 返回所在资源路径上的一个资源, 只能应用在unity的编辑器模式下,安卓等平台无效 static function LoadAssetAtPath (assetPath : s ...

  7. UML中的六种关系的比较与学习

    通过不断的学习并绘制UML图,整个画图的过程中深刻体会到其核心部分还是理解事物之间的关系,总结六大关系来深入学习,主要关系有六种:继承.实现.依赖.关联.聚合.组合. 区别于联系:         1 ...

  8. 对象图 Object Diagram

    一.用一张图来介绍一下对象图的基本内容 二.对象图与类图的基本区别 三.对象图实例

  9. bndtools教程

    使用工具编程的确能给人们带来很多便利,但是在不会用之前,且缺乏相应的中文资料让你去了解时,真是一种折磨,同时也是一种挑战. bndTools其实就是用来开发OSGi的一个工具,它为开发提供了便利,具体 ...

  10. Pentaho Data Integration笔记 (一):安装

    介绍 Pentaho Data Integration (PDI) is an extract, transform, and load (ETL) solution that uses an inn ...