Android源码编译并预装带JNI的apk


说明:

以下文档中使用 *android_src 目录代表我的android6.0源码的根目录。*

1.在eclipse或者androidstudio中新建一个工程HelloWorld。
在包com/sk/helloworld 下面新建一个java文件。内容如下:

package com.sk.helloworld;

import android.R.integer;

public class JNICore {


    static{
        System.loadLibrary("JNICore");
    }

    public native String getStringFromNative();
    public native boolean isNativeOK();

}

测试MainActivity.java文件如下:

package com.sk.helloworld;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    TextView tView = (TextView) findViewById(R.id.tv);


        JNICore jniCore = new JNICore();
        boolean b = jniCore.isNativeOK();

        if(b) {
            tView.setText(jniCore.getStringFromNative());
        }else{
        tView.setText("isNativeOK false");
    }
    }
}

a. 终端进入HelloWorld的bin/classes目录。执行以下语句:

javah -classpath ./ -d ../../jni -jni  com.sk.helloworld.JNICore

会在jni目录生成一个com.sk.helloworld.JNICore.h头文件。可按此头文件在当前目录写一个同名的cpp源码文件。内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>


jboolean mBoolean = JNI_FALSE;


#ifdef __cplusplus
extern "C" {
#endif




/*
 * Class:     com_sk_helloworld_JNICore
 * Method:    getStringFromNative
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_sk_helloworld_JNICore_getStringFromNative
  (JNIEnv *env, jobject thiz) {

    jstring des = (jstring)env->NewStringUTF("The string \"Hello World~\"is get from native.");

    return des;
}

/*
 * Class:     com_sk_helloworld_JNICore
 * Method:    isNativeOK
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_sk_helloworld_JNICore_isNativeOK
  (JNIEnv *env, jobject obj) {

    mBoolean = JNI_TRUE;

    return mBoolean;
}


#ifdef __cplusplus
}
#endif
#endif

b.再该目录下面新建两个文件Android.mk Application.mk。
Android.mk文件定义生成一个名为libJNICore.so的动态链接库。内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libJNICore

LOCAL_CPP_EXTENSION := .cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES := com_sk_helloworld_JNICore.cpp


LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

Application.mk文件配置NDK编译的选项,

APP_OPTIM ———– 定义是debug还是release版本
APP_PLATFORM—— 定义编译时的ndk版本
APP_ABI —————-定义生成的 取得值包括:(1)、32位:armeabi、armeabi-v7a、x86、mips;(2)、64 位:arm64-v8a,x86_64, mips64;
APP_STL ————–定义C++库。这里我使用的c++源文件。且引用了iostream库。

文件内容如下:

APP_OPTIM := debug
APP_PLATFORM := android-19
APP_ABI := armeabi
APP_STL := stlport_static

2.在androi_src/packages/apps/HelloWorld目录下编写Android.mk文件。用来定义生成apk文件,并拷贝到android_src/out/target/product/generic/system/app/HelloWorld下面。该文件有一个特别的地方
LOCAL_JNI_SHARED_LIBRARIES := libJNICore 这条语句定义使用jni生成的动态链接库。如果没有这一句,将不会编译jni目录下面的c++文件。我之前在这里耗了很多时间,一直没有生成so库。导致后面运行HelloWorld.apk的时候找不到库而挂掉。
include $(BUILD_PACKAGE)这条语句定义要打包成apk。生成后会自动把生成的apk及so库文件一并拷贝到android_src/out/target/product/generic/system/app/HelloWorld下面。编译后可到此目录查看是否有apk及so库。

该文件内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_CERTIFICATE := platform

LOCAL_PACKAGE_NAME := HelloWorld

LOCAL_JNI_SHARED_LIBRARIES := libJNICore


include $(BUILD_PACKAGE)

# Use the following include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))

**

工程新建完毕,可在eclipse工具上测试是否能编译通过。然后将HelloWorld文件夹拷贝到android_src/packages/apps/目录。删除HelloWorld目录下的bin和gen目录。

**

a.准备工作就绪,进行编译。android源码太大。编译耗时。但好在android提供了模块儿编译。在根目录执行source build/envsetup.sh后会增加几个命令。简单介绍需要用到的:

m:编译所有的模块

mm:编译当前目录下的模块,当前目录下要有Android.mk文件

mmm:编译指定路径下的模块,指定路径下要有Android.mk文件

这里我们到android_src/packages/apps/HelloWorld目录下,执行mm命令进行编译。完成后,会在android_src/out/target/product/generic/system/app/下生成HelloWorld目录。

然后将生成的apk打包进系统文件。
在源码根目录使用 如 命令打包:

make snod

b.之后就可以使用emulator运行模拟器,进行运行刚才增加的HelloWorld应用。
运行结果如下:

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值