在上一篇文章中,我写了如何在Linux下引用.so文件,那是为在Android下引用/system/lib下的系统库做热身。接下来我们看一下如何在Android环境下引用/system/lib下的.so文件(若您也对此有所了解,还望不吝赐教后面的问题,先谢!)。

        为避免讲得混淆,先将我的代码的结构贴出来。

        首先,新建Android工程:AndroidJniTest,在AndroidJniTestActivity.java中的代码如下:

package mars.com;import android.app.Activity;import android.os.Bundle;public class AndroidJniTestActivity extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        System.loadLibrary("test");        CallNative callnative = new CallNative();        byte[] cmd = {(byte)'\u004c'};        int a = callnative.writeCmd(cmd, "/system/lib");            }}


再在包mars.com下建立文件:CallNative.java  代码:

package mars.com;public class CallNative { public native byte[] readCmd(String path); public native int writeCmd(byte[] cmd, String path);}


利用javah工具创建本地库文件的头文件mars_com_CallNative.h  代码:

/* DO NOT EDIT THIS FILE - it is machine generated */#include /* Header for class mars_com_CallNative */#ifndef _Included_mars_com_CallNative#define _Included_mars_com_CallNative#ifdef __cplusplusextern "C" {#endif/* * Class:     mars_com_CallNative * Method:    readCmd * Signature: (Ljava/lang/String;)[B */JNIEXPORT jbyteArray JNICALL Java_mars_com_CallNative_readCmd  (JNIEnv *, jobject, jstring);/* * Class:     mars_com_CallNative * Method:    writeCmd * Signature: ([BLjava/lang/String;)I */JNIEXPORT jint JNICALL Java_mars_com_CallNative_writeCmd  (JNIEnv *, jobject, jbyteArray, jstring);#ifdef __cplusplus}#endif#endif
   
   
   
   

 

 

至于如何生成此头文件,可自行学习,这里不多讲了

第二,在工程目录下建立文件夹:jni,将文件mars_com_CallNative.h 拷贝到此目录下,再在此目录下建立文件test.c,代码:

#include"mars_com_CallNative.h"

#include#include#include #include #include #include #include#include#include"include/telephony/ril.h"#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "keymatch", __VA_ARGS__)JNIEXPORT jbyteArray JNICALL Java_mars_com_CallNative_readCmd(JNIEnv *evn, jobject obj, jstring jstr){ exit(0);}JNIEXPORT jint JNICALL Java_mars_com_CallNative_writeCmd(JNIEnv *evn, jobject jobj, jbyteArray jba, jstring jstr){ return 56;}jint JNI_OnLoad(JavaVM* vm, void* reserved) { LOGD("JNI ONLOAD success!"); char *path = "/system/lib/libril.so"; void* filehandle0 = dlopen(path, RTLD_LAZY|RTLD_GLOBAL ); //引用path指向的库:/system/lib/libril.so char *ll; int pid; if(filehandle0) {  LOGD("open so success!");  char*(*requesttostring)(int);  if( 0 == pid)  {   sleep(1);//子进程睡眠一秒   requesttostring = (char *(*)(int))dlsym(filehandle0, "requestToString");   pid = fork();   if( requesttostring )   {    LOGD("call function requesttostring OK!");    ll = requesttostring(RIL_REQUEST_GET_NEIGHBORING_CELL_IDS);    //RIL_REQUEST_GET_NEIGHBORING_CELL_IDS定义在include/telephony/ril.h中    LOGD("the value of requesttostring is %s", *ll);   }   else   {    LOGD("call function getinformation! ERROR!");   }   LOGD("ok");  }  else if(0 < pid)  {   LOGD("in the parent %s\n",getpid());  }  else LOGD("fork error"); }}


将Android源码hardware/ril下的include文件夹也拷贝到jni文件夹下(因为在requesttostring(RIL_REQUEST_GET_NEIGHBORING_CELL_IDS)中使用的RIL_REQUEST_GET_NEIGHBORING_CELL_IDS在include文件夹下的ril.h中定义了)。
        在jni文件夹下新建Android.mk文件,内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := testLOCAL_SRC_FILES := test.cLOCAL_LDLIBS := -llogLOCAL_CERTIFICATE := platforminclude $(BUILD_SHARED_LIBRARY)

        第三,接下来就是编译的时候了。在cygwin下 $ndk/ndk-build

显示编译通过了,F5刷新工程,发现在工程目录下多了一下文件夹:libs,其中就包含了生成的文件:libtest.so

        最后,运行。发现在Logcat下有这些信息:

。。。。。。

        好了,问题来了。问题一、从绿色部分的内容来看,应该是成功引用了/system/lib/libril.so的,但为什么在上面只输出了

在test.c中,我用了fork创建了两个进程,而且在子进程中sleep(1),睡眠了一秒,按理说在这时应该运行父进程,也就是说应该运行如下部分代码

else if(0 < pid)
  {
   LOGD("in the parent %s\n",getpid());
  }

Logcat   :   in the parent + pid  ,但问题是在运行时没有输出,这是why?? 

        问题二、在Logcat中可以看到,程序跑着跑着就死了

是怎么死的呢?会不会是因为在模拟器中无法进行通信(libril.so是通信模块的一部分)?但如果是意外终止的话,模拟器中却一直是运行正常的,没有弹出意外终止的对话框。

        这个问题困扰了我很久,希望能得到高人指点,谢谢!

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   


更多相关文章

  1. Android培训班(53)
  2. Android中的OpenSL ES是如何实现的?
  3. 【边做项目边学Android】知识点:Adapter适配器
  4. Android(安卓)系统 目录 分析
  5. android工程中不自动生成Android(安卓)Dependencies的解决方式
  6. 将tensorflow训练好的模型移植到android
  7. 《疯狂Android讲义》学习笔记一
  8. HOWTO install and setup Android(安卓)NDK for Windows(Android
  9. NPM 和webpack 的基础使用

随机推荐

  1. Android对话框的几种形式
  2. Android(安卓)AlertDialog学习
  3. Android(安卓)Adapter的使用
  4. 全局窗口一
  5. android 图片轮播(banner)无限轮播
  6. android recovery模式选项中索引改进
  7. Android(安卓)强制横屏
  8. android中去掉button的边框和EditText中
  9. Android(安卓)各种工具类 图片下载工具类
  10. 【Arcgis for android】Error inflating