android so 不能编译进,.so正确编译进apk里打包

本文主要讲述Android开发中.so文件编译问题。指出jni下的Android.mk里c文件未写全、app下的Android.mk未包含jni/Android.mk会导致编译问题。详细给出JNI和项目下的Android.mk配置示例,按此配置可成功编译出.so文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我先说说我犯错的 地方。 1.jni下的Android.mk里的c文件 没有写全 LOCAL_SRC_FILES :=

2.app下的Android.mk没有这句:include $(LOCAL_PATH)/jni/Android.mk

好。这样之后 make android的时候就不会报错了。会在out/target/product/generic/obj/lib下生成相应的.so。这里有就说明你的.so编译成功。

JNI下的Android.mk:

#

# Copyright 2009 Cedric Priscal

#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.

# You may obtain a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

#

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#TARGET_PLATFORM := android-3

LOCAL_MODULE_TAGS := eng

#LOCAL_MODULE_TAGS := optional

# This is the target being built.

LOCAL_MODULE    := libserialport         //

# All of the source files that we will compile.

LOCAL_SRC_FILES :=  \

SerialPort.c \

RemoTIAPI.c                                                //这里只要你的jni下有多少c文件都要写完。不然。。。

# All of the shared libraries we link against.

LOCAL_SHARED_LIBRARIES := \

libutils

# No static libraries.

LOCAL_STATIC_LIBRARIES :=

# Also need the JNI headers.

LOCAL_C_INCLUDES += \

$(JNI_H_INCLUDE)

# No special compiler flags.

LOCAL_CFLAGS +=

#LOCAL_LDLIBS := -ldl -llog

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)  //编译so库

项目下的Android.mk:

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

#  LOCAL_MODULE_TAGS := user, eng

LOCAL_MODULE_TAGS := optional                     //这里也要注意!这里 要与你make android源码后出现的列表里的TARGET_BUILD_VARIANT=xxx 一样

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME :=FieldTest

#  LOCAL_CERTIFICATE := platform

LOCAL_JNI_SHARED_LIBRARIES := libserialport         //安装库

## Use the folloing include to make our RemoteControl apk.

include $(BUILD_PACKAGE)                                        //编译成apk

include $(LOCAL_PATH)/jni/Android.mk                     //调用库的编译

# ============================================================

# Also build all of the sub-targets under this one: the shared library.

#include $(call all-makefiles-under,$(LOCAL_PATH))

其他的 注释可以在网上搜到。

### 如何让Android动态参与编译但不在最终APK打包 在Gradle配置文件 `build.gradle` 中,可以通过特定的方式实现动态(如 `.so` 文件或其他资源)仅参与编译而不被打包到最终的 APK 中。以下是具体的解决方案: #### 使用 `packagingOptions` 排除指定文件 通过设置 `packagingOptions.exclude` 来排除不需要打包的动态文件。例如,假设有一个名为 `libexample.so` 的动态文件不希望被包含在最终的 APK 中,则可以在 `build.gradle` 文件中添加以下代码[^1]: ```gradle android { packagingOptions { exclude 'lib/armeabi-v7a/libexample.so' exclude 'lib/x86/libexample.so' } } ``` 上述代码的作用是告诉 Gradle 构建工具,在打包过程中忽略掉路径下的指定 `.so` 文件。 #### 使用 `sourceSets` 自定义源码目录并控制资源范围 另一种方法是利用 `sourceSets` 配置来自定义源码和资源目录,并明确指出哪些部分应该参与编译而不会入最终产物。例如[^2]: ```gradle android { sourceSets { main { jniLibs.srcDirs = [] // 清空默认的jniLibs目录 } } tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -> pkgTask.jniFolders = new HashSet<File>() // 移除所有JNI文件夹 } } ``` 此段脚本首先清除了默认用于存储本地共享对象 (`.so`) 文件的位置 (`jniLibs.srcDirs`) ,接着一步确保没有任何 JNI 会被加入到最后的应用程序包。 #### 处理依赖冲突的情况 当遇到第三方之间存在版本差异引发的冲突时,可以借助强制解析某个具体版本的方法解决这个问题。比如下面的例子展示了如何固定支持的版本为 28.0.0 [^3]: ```gradle configurations.all { resolutionStrategy.force 'com.android.support:support-v4:28.0.0' } ``` 另外还可以单独针对某些模块应用排除策略来规避不必要的组件加载来影响整体大小或者功能正常运作 [^4]: ```gradle dependencies { implementation('some.library') { exclude group: 'org.unwanted', module: 'unneeded-feature' } } ``` 以上就是在 Android 开发环境下关于如何使动态链接只经历编译阶段却无需实际嵌入至分发版中的几种常见技巧介绍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值