在前面我简单的描述了Android的启动过程http://blog.csdn.net/codectq/article/details/7383231,但终究是不够完善。

现在在工程中遇到了实际的问题,反过来阅读下代码,再重新审视一下在kernel启动之后的ANDROID启动过程。

在frameworks/base/services/java/com/android/server文件夹下的SystemServer.cpp文件。在此文件中调用了init1()函数,文件中对次函数的描述为:这个方法是从Zygote中调用来初始化系统。这将引起本地的服务(Surfaceflinger,audioflinger等)开启。在这些完成之后将回调init2()来开始android服务。

从上面的描述中我们可以得知两个方面:一是在android的服务中,我们分两种服务,一种是native服务,另一种是android服务。二是我们的本地服务是在init1()的过程中完成的,而android服务是在init2()的过程中完成的。

从实际的真机的启动过程的打印信息我们也能够看出,在启动的过程中,我们首先会启动SurfaceFlinger,AudioFlinger然后开始启动dalikvm,从而进入对Zygote和System并且通过调用system_init()函数和sysproc来启动Android runtime 启动native service。通过回调init2(),Android service\thread pool从而进入systemserver,运行systemserver线程,将注册到systemserver中的服务启动。

如果我们想借助Android本身的架构来完成添加我们的服务的目的的情况下我们不妨就利用这些。

在我们通过使用JNI机制使得上层的java应用能够调用native service。而具体的实现就是将.cpp文件放在JNI文件夹下,而将.java文件放在java文件夹下。具体步骤如下:

在上文中,我们说过我们可以借助Android自身架构的东西来完成我们的JNI服务,而不必每个细节都自己完成。并且我们提到我们会调用AndroidRuntime所以我们可以将服务注册到AndroidRuntime.cpp文件中。下面是个经典的例子,此处做个摘抄地址为http://dongyulong.blog.51cto.com/1451604/545496(但是不知道是不是原作者)

frameworks/base/core/jni路径下创建例子android_mytest_hellojni.cpp文件,这个文件就是在JNI层实现接口。文件内容如下:(可参考同一目录下的android_debug_JNITest.cpp文件编写)

#defineLOG_TAG"HelloJNI"
#include"jni.h"
#include"nativehelper/JNIHelp.h"
#include"utils/Log.h"
#include"utils/misc.h"

namespaceandroid{
staticjstring android_mytest_hellojni_displayString(JNIEnv*env,jclass clazz)
{
returnenv->NewStringUTF("Hello from JNI!");
}

/*
* JNI registration.
*/

staticJNINativeMethod gMethods[]={
/* name, signature, funcPtr */
{"displayString","()Ljava/lang/String;",
(void*)android_mytest_hellojni_displayString},

};
intregister_android_mytest_hellojni(JNIEnv*env)
{//此处的目录结构就是在Javaframework层的文件目录,且必须一致

returnjniRegisterNativeMethods(env,"android/mytest/hellojni",
gMethods,NELEM(gMethods));
}
};

2.JNI层:对编译的修改配置

2.1修改/Android/android-1.6_r2/frameworks/base/core/jni目录下的Android.mk文件,在LOCAL_SRC_FILES:= \下面加上
android_mytest_hellojni.cpp \
2.2修改/Android/android-1.6_r2/frameworks/base/core/jni目录下的AndroidRuntime.cpp文件在extern int后面添加
extern int register_android_mytest_hellojni(JNIEnv* env);
然后在static const RegJNIRec gRegJNI[] ={下面添加
REG_JNI(register_android_mytest_hellojni),
这样,JNI层的修改就到此为止了。

frameworks/base/core/java/android/新建文件目录mytest,在该目录下新建文件hellojni.java声明接口。内容如下:(可以参考android-1.6_r2/frameworks/base/core/java/android/debug目录下的JNITest.java文件编写)

packageandroid.mytest;
publicclasshellojni{
publichellojni(){}
//此处声明为public所以才可以被application调用

publicstaticnativeStringdisplayString();
}

4.下面我们要对我们做过更改的libandroid_runtime.so和framework.jar进行重新编译。

在源代码工程目录下输入make libandroid_runtime重新编译生成libandroid_runtime.so

target thumb C++: libandroid_runtime <= frameworks/base/core/jni/android_mytest_hellojni.cpp

target thumb C++: libandroid_runtime <= frameworks/base/core/jni/AndroidRuntime.cpp

target SharedLib: libandroid_runtime (out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_runtime_intermediates/LINKED/libandroid_runtime.so)

target Prelink: libandroid_runtime (out/target/product/generic/symbols/system/lib/libandroid_runtime.so)

target Strip: libandroid_runtime (out/target/product/generic/obj/lib/libandroid_runtime.so)

Install:out/target/product/generic/system/lib/libandroid_runtime.so

然后再输入make framework重新编译生成framework.jar

Install:out/target/product/generic/system/framework/framework.jar


更多相关文章

  1. C语言函数以及函数的使用
  2. manifest文件
  3. H5 Web网页通过JS(JavaScript)脚本调用Android本地原生方法函数
  4. android不是内部或外部命令,也不是可运行的程序或批处理文件
  5. android sdk 文件目录含义介绍
  6. 如何查看android数据文件?
  7. android 添加文件打开方式,找了很久终于找到了,收藏起来吧
  8. Android读取文件
  9. freetype 在android编译时上的一个makefile文件

随机推荐

  1. android基础知识点复习之短信发送
  2. 不停地切换两张图片ViewFlipper
  3. ListPreference
  4. 手工下载android sdk或者system images等
  5. 2.5.2 使用alertdialog 创建列表对话框
  6. Android中的时间日期选择器
  7. mac 编译 Android(安卓)系统杂记
  8. 2.6.1 使用toast显示提示信息框
  9. ViewFlipper+GestureDetector实现不循环
  10. GridView示例2(自动增长)