- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 Android 开发的初学者,我想了解 JavaCPP .我想执行 C++
函数来自 Java
在 Android
内应用。在我的示例中,我只使用了一个简单的 TextView
打印我从 C++
收到的内容的小部件.
按照文档,在应用程序的 build.gradle
中我已经包含了我的 javacpp
库依赖
dependencies {
implementation 'org.bytedeco:javacpp:1.5.4'
}
为了在我的应用程序中使用它。我正在一个 Native C++ Android Studio 模板项目中进行测试。
package com.example.javacplusplus;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="NativeLibrary.h")
@Namespace("NativeLibrary")
public class NativeLibrary {
public static class NativeClass extends Pointer {
static { Loader.load(); }
public NativeClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property();
public native void set_property(String property);
// to access the member variable directly
public native @StdString String property();
public native void property(String property);
}
}
NativeLibrary.h :
#ifndef NATIVELIBRARY_H
#define NATIVELIBRARY_H
#include <string>
namespace NativeLibrary {
class NativeClass {
public:
const std::string& get_property();
void set_property(const std::string& property);
std::string property;
};
}
#endif // NATIVELIBRARY_H
NativeLibrary.cpp :
#include "NativeLibrary.h"
namespace NativeLibrary {
const std::string& NativeClass::get_property() { return property; }
void NativeClass::set_property(const std::string& property) { this->property = property; }
} // namespace NativeLibrary
CMakeLists.txt :
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
NativeLibrary.cpp
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
请注意,native-lib.cpp 只是模板中使用的 C++ 文件,我暂时忽略它。
app
模块):
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.javacplusplus"
minSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'org.bytedeco:javacpp:1.5.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
MainActivity.java :
package com.example.javacplusplus;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
NativeLibrary.NativeClass l = new NativeLibrary.NativeClass();
l.set_property("Hello World!");
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(l.property());
// tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
应用程序构建良好,但它在运行时在
NativeLibrary.NativeClass l = new NativeLibrary.NativeClass();
内崩溃, 带有消息
couldn't find "libjniNativeLibrary.so"
这是我的崩溃日志:
--------- beginning of crash
2020-11-16 00:57:38.557 13506-13506/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.javacppapp, PID: 13506
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/base.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_dependencies_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_resources_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_0_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_1_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_2_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_3_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_4_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_5_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_6_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_7_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_8_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/base.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_dependencies_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_resources_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_0_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_1_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_2_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_3_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_4_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_5_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_6_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_7_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_8_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_9_apk.apk!/lib/x86, /system/lib]]] couldn't find "libjniNativeLibrary.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
at java.lang.System.loadLibrary(System.java:1669)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1683)
at org.bytedeco.javacpp.Loader.load(Loader.java:1300)
at org.bytedeco.javacpp.Loader.load(Loader.java:1123)
at com.example.javacppapp.NativeLibrary$NativeClass.<clinit>(NativeLibrary.java:10)
at com.example.javacppapp.MainActivity.onCreate(MainActivity.java:22)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
2020-11-16 00:57:38.557 13506-13506/? E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
请注意,当我在桌面 x64 上执行该示例时,该示例正在运行。因此,例如,使用以下
NativeLibrary.java
文件:
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="NativeLibrary.h")
@Namespace("NativeLibrary")
public class NativeLibrary {
public static class NativeClass extends Pointer {
static { Loader.load(); }
public NativeClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property();
public native void set_property(String property);
// to access the member variable directly
public native @StdString String property();
public native void property(String property);
}
public static void main(String[] args) {
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
NativeClass l = new NativeClass();
l.set_property("Hello World!");
System.out.println(l.property());
}
}
的输出
$ javac -cp javacpp.jar NativeLibrary.java
$ java -jar javacpp.jar NativeLibrary
$ java -cp javacpp.jar NativeLibrary
$ Hello World!
是
Hello World!
所以它工作正常。但我不知道为什么它在 Android 应用程序中不起作用。
libjniNativeLibrary.so
?为了完成设置,我需要添加一些东西吗?也许
libjniNativeLibrary.so
需要以某种方式生成?
Build Plugin
和
Platform Plugin
到项目的
build.gradle
文件;这是现在的样子:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
plugins {
id 'java-library'
id 'java-gradle-plugin'
id 'org.bytedeco.gradle-javacpp-build' version "$javacppVersion"
id 'org.bytedeco.gradle-javacpp-platform' version "$javacppVersion"
}
ext {
javacppPlatform = 'android-arm64' // or any other platform, defaults to Loader.getPlatform()
}
dependencies {
implementation gradleApi()
api "org.bytedeco:javacpp:$javacppVersion"
}
allprojects {
repositories {
google()
jcenter()
}
}
// Note: Had to comment this as I was getting the error > Cannot add task 'clean' as a task with that name already exists.
//task clean(type: Delete) {
// delete rootProject.buildDir
//}
tasks.withType(org.bytedeco.gradle.javacpp.BuildTask) {
// set here default values for all build tasks below, typically just includePath and linkPath,
// but also properties to set the path to the NDK and its compiler in the case of Android
}
javacppBuildCommand {
// typically set here the buildCommand to the script that fills up includePath and linkPath
}
javacppBuildParser {
// typically set here the classOrPackageNames to class names implementing InfoMap
}
javacppBuildCompiler {
// typically set here boolean flags like copyLibs
}
该项目同步没有错误,但是当我运行它时,我得到:
> Task :javacppBuildParser FAILED
Execution failed for task ':javacppBuildParser'.
> app/build/intermediates/javac/debug/classes/com/example/myjavacppapp/BuildConfig (wrong name: com/example/myjavacppapp/BuildConfig)
是因为我没有在里面写任何东西
javacppBuildCommand
,
javacppBuildParser
和
javacppBuildParser
?
build.gradle
文件:
android {
applicationVariants.all { variant ->
variant.javaCompiler.doLast {
println 'javacpp ' + variant.name
javaexec {
main 'org.bytedeco.javacpp.tools.Builder'
classpath '/home/jacob/Work/other/sandbox/java/javacpp3/app/libs/javacpp.jar'
args '-cp', variant.javaCompiler.destinationDir,
'-properties', 'android-arm',
'-Dplatform.root=/home/jacob/.android/sdk/ndk/21.1.6352462',
'-Dplatform.compiler=/home/jacob/.android/sdk/ndk/21.1.6352462/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++',
'-Dplatform.includepath=/home/jacob/.android/sdk/ndk/21.1.6352462/sources/cxx-stl/gnu-libstdc++/include:src/main/cpp',
'-Dplatform.linkpath=/home/jacob/.android/sdk/ndk/21.1.6352462/sources/cxx-stl/llvm-libc++/libs/arm64-v8a',
'-d', 'libs/armeabi'
}
println 'javacpp done'
}
}
sourceSets.main {
jniLibs.srcDir 'libs'
jni.srcDirs = [] // disable automatic ndk-build call
}
}
gradle 同步运行正常,但是当我构建项目时,我得到:
> Task :app:compileDebugJavaWithJavac FAILED
javacpp debug
Exception in thread "main" java.lang.NoClassDefFoundError: androidx/appcompat/app/AppCompatActivity
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at org.bytedeco.javacpp.tools.UserClassLoader.findClass(UserClassLoader.java:72)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.bytedeco.javacpp.tools.ClassScanner.addClass(ClassScanner.java:61)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingFile(ClassScanner.java:75)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:87)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:85)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:85)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:85)
at org.bytedeco.javacpp.tools.ClassScanner.addPackage(ClassScanner.java:99)
at org.bytedeco.javacpp.tools.Builder.classesOrPackages(Builder.java:672)
at org.bytedeco.javacpp.tools.Builder.main(Builder.java:962)
Caused by: java.lang.ClassNotFoundException: androidx.appcompat.app.AppCompatActivity
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at org.bytedeco.javacpp.tools.UserClassLoader.findClass(UserClassLoader.java:72)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 23 more
FAILURE: Build failed with an exception.
* Where:
Build file '/home/jacob/Work/other/sandbox/java/javacpp3/app/build.gradle' line: 48
* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
> Process 'command '/home/jacob/.android/studio/jre/bin/java'' finished with non-zero exit value 1
知道如何解决这个问题吗?
最佳答案
我在这里发布了一个完整的工作示例:
https://github.com/bytedeco/sample-projects/tree/master/gradle-javacpp-android
作为引用,我们可以通过以下步骤重现此项目:
app/build.gradle
中添加如下内容文件(在以通常方式应用 org.bytedeco.gradle-javacpp-build
插件之后)和 android.applicationVariants.all { variant ->
def variantName = variant.name.capitalize() // either "Debug" or "Release"
def javaCompile = project.tasks.getByName("compile${variantName}JavaWithJavac")
def generateJson = project.tasks.getByName("generateJsonModel$variantName")
// Compiles NativeLibraryConfig.java
task "javacppCompileJava$variantName"(type: JavaCompile) {
include 'com/example/myapplication/NativeLibraryConfig.java'
source = javaCompile.source
classpath = javaCompile.classpath
destinationDir = javaCompile.destinationDir
}
// Parses NativeLibrary.h and outputs NativeLibrary.java
task "javacppBuildParser$variantName"(type: org.bytedeco.gradle.javacpp.BuildTask) {
dependsOn "javacppCompileJava$variantName"
classPath = [javaCompile.destinationDir]
includePath = ["$projectDir/src/main/cpp/"]
classOrPackageNames = ['com.example.myapplication.NativeLibraryConfig']
outputDirectory = file("$projectDir/src/main/java/")
}
// Compiles NativeLibrary.java and everything else
javaCompile.dependsOn "javacppBuildParser$variantName"
// Generates jnijavacpp.cpp and jniNativeLibrary.cpp
task "javacppBuildCompiler$variantName"(type: org.bytedeco.gradle.javacpp.BuildTask) {
dependsOn javaCompile
classPath = [javaCompile.destinationDir]
classOrPackageNames = ['com.example.myapplication.NativeLibrary']
compile = false
deleteJniFiles = false
outputDirectory = file("$projectDir/src/main/cpp/")
}
// Picks up the C++ files listed in CMakeLists.txt
generateJson.dependsOn "javacppBuildCompiler$variantName"
}
CMakeLists.txt
文件以包含生成的 .cpp
文件。 关于java - 使用 JavaCPP 在 Java Android 应用程序中运行 C++ 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64847061/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!