AndroidStudioにてJNIを用いてC言語の文字列をJavaへ受け渡したいと考えています.
NDK-Buildを使い共有ライブラリの作成も行いましたがJavaコード内で
定義したC言語の関数名が反応せずエラーが発生しています.
この場合作成した共有ライブラリに問題があるのか,または開発環境の設定に問題があるのでしょうか?
C
1#include "hello-jni.h" 2 3JNIEXPORT jstring JNICALL 4Java_android_mobi_monaca_HelloWorldPlugin_stringFromJNI( JNIEnv* env, 5 jobject thiz ) 6{ 7 return (*env)->NewStringUTF(env, "Hello from JNI test !"); 8}
gradle
1 2apply plugin: 'com.android.application' 3 4buildscript { 5 repositories { 6 mavenCentral() 7 jcenter() 8 } 9 10 dependencies { 11 classpath 'com.android.tools.build:gradle:2.3.2' 12 } 13} 14 15allprojects { 16 repositories { 17 mavenCentral(); 18 jcenter() 19 } 20} 21 22task wrapper(type: Wrapper) { 23 gradleVersion = '2.14.1' 24} 25 26ext { 27 apply from: 'CordovaLib/cordova.gradle' 28 if (!project.hasProperty('cdvCompileSdkVersion')) { 29 cdvCompileSdkVersion = null; 30 } 31 if (!project.hasProperty('cdvBuildToolsVersion')) { 32 cdvBuildToolsVersion = null; 33 } 34 if (!project.hasProperty('cdvVersionCode')) { 35 cdvVersionCode = null 36 } 37 if (!project.hasProperty('cdvMinSdkVersion')) { 38 cdvMinSdkVersion = null 39 } 40 if (!project.hasProperty('cdvBuildMultipleApks')) { 41 cdvBuildMultipleApks = null 42 } 43 if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) { 44 cdvReleaseSigningPropertiesFile = null 45 } 46 if (!project.hasProperty('cdvDebugSigningPropertiesFile')) { 47 cdvDebugSigningPropertiesFile = null 48 } 49 if (!project.hasProperty('cdvBuildArch')) { 50 cdvBuildArch = null 51 } 52 53 cdvPluginPostBuildExtras = [] 54} 55 56// PLUGIN GRADLE EXTENSIONS START 57// PLUGIN GRADLE EXTENSIONS END 58 59def hasBuildExtras = file('build-extras.gradle').exists() 60if (hasBuildExtras) { 61 apply from: 'build-extras.gradle' 62} 63 64// Set property defaults after extension .gradle files. 65if (ext.cdvCompileSdkVersion == null) { 66 ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget() 67} 68if (ext.cdvBuildToolsVersion == null) { 69 ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools() 70} 71if (ext.cdvDebugSigningPropertiesFile == null && file('debug-signing.properties').exists()) { 72 ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties' 73} 74if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.properties').exists()) { 75 ext.cdvReleaseSigningPropertiesFile = 'release-signing.properties' 76} 77 78// Cast to appropriate types. 79ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean(); 80ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion) 81ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode) 82 83def computeBuildTargetName(debugBuild) { 84 def ret = 'assemble' 85 if (cdvBuildMultipleApks && cdvBuildArch) { 86 def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch 87 ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1); 88 } 89 return ret + (debugBuild ? 'Debug' : 'Release') 90} 91 92// Make cdvBuild a task that depends on the debug/arch-sepecific task. 93task cdvBuildDebug 94cdvBuildDebug.dependsOn { 95 return computeBuildTargetName(true) 96} 97 98task cdvBuildRelease 99cdvBuildRelease.dependsOn { 100 return computeBuildTargetName(false) 101} 102 103task cdvPrintProps << { 104 println('cdvCompileSdkVersion=' + cdvCompileSdkVersion) 105 println('cdvBuildToolsVersion=' + cdvBuildToolsVersion) 106 println('cdvVersionCode=' + cdvVersionCode) 107 println('cdvMinSdkVersion=' + cdvMinSdkVersion) 108 println('cdvBuildMultipleApks=' + cdvBuildMultipleApks) 109 println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile) 110 println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile) 111 println('cdvBuildArch=' + cdvBuildArch) 112 println('computedVersionCode=' + android.defaultConfig.versionCode) 113 android.productFlavors.each { flavor -> 114 println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode) 115 } 116} 117 118android { 119 sourceSets { 120 main { 121 manifest.srcFile 'AndroidManifest.xml' 122 java.srcDirs = ['src'] 123 resources.srcDirs = ['src'] 124 aidl.srcDirs = ['src'] 125 renderscript.srcDirs = ['src'] 126 res.srcDirs = ['res'] 127 assets.srcDirs = ['assets'] 128 jniLibs.srcDirs = ['libs'] 129 } 130 } 131 132 defaultConfig { 133 versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode")) 134 applicationId privateHelpers.extractStringFromManifest("package") 135 136 if (cdvMinSdkVersion != null) { 137 minSdkVersion cdvMinSdkVersion 138 } 139 } 140 141 lintOptions { 142 abortOnError false; 143 } 144 145 compileSdkVersion cdvCompileSdkVersion 146 buildToolsVersion cdvBuildToolsVersion 147 148 if (Boolean.valueOf(cdvBuildMultipleApks)) { 149 productFlavors { 150 armv7 { 151 versionCode defaultConfig.versionCode*10 + 2 152 ndk { 153 abiFilters 'armeabi-v7a' 154 } 155 } 156 x86 { 157 versionCode defaultConfig.versionCode*10 + 4 158 ndk { 159 abiFilters 'x86' 160 } 161 } 162 all { 163 ndk { 164 abiFilters "all", "" 165 } 166 } 167 } 168 } 169 170 171 compileOptions { 172 sourceCompatibility JavaVersion.VERSION_1_6 173 targetCompatibility JavaVersion.VERSION_1_6 174 } 175 176 if (cdvReleaseSigningPropertiesFile) { 177 signingConfigs { 178 release { 179 // These must be set or Gradle will complain (even if they are overridden). 180 keyAlias = "" 181 keyPassword = "__unset" // And these must be set to non-empty in order to have the signing step added to the task graph. 182 storeFile = null 183 storePassword = "__unset" 184 } 185 } 186 buildTypes { 187 release { 188 signingConfig signingConfigs.release 189 } 190 } 191 addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release) 192 } 193 if (cdvDebugSigningPropertiesFile) { 194 addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug) 195 } 196} 197 198dependencies { 199 compile fileTree(dir: 'libs', include: '*.jar') 200 // SUB-PROJECT DEPENDENCIES START 201 debugCompile(project(path: "CordovaLib", configuration: "debug")) 202 releaseCompile(project(path: "CordovaLib", configuration: "release")) 203 // SUB-PROJECT DEPENDENCIES END 204} 205 206def promptForReleaseKeyPassword() { 207 if (!cdvReleaseSigningPropertiesFile) { 208 return; 209 } 210 if ('__unset'.equals(android.signingConfigs.release.storePassword)) { 211 android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ') 212 } 213 if ('__unset'.equals(android.signingConfigs.release.keyPassword)) { 214 android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: '); 215 } 216} 217 218gradle.taskGraph.whenReady { taskGraph -> 219 taskGraph.getAllTasks().each() { task -> 220 if (task.name == 'validateReleaseSigning' || task.name == 'validateSigningRelease') { 221 promptForReleaseKeyPassword() 222 } 223 } 224} 225 226def addSigningProps(propsFilePath, signingConfig) { 227 def propsFile = file(propsFilePath) 228 def props = new Properties() 229 propsFile.withReader { reader -> 230 props.load(reader) 231 } 232 233 def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile')) 234 if (!storeFile.isAbsolute()) { 235 storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile()) 236 } 237 if (!storeFile.exists()) { 238 throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath()) 239 } 240 signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias') 241 signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword)) 242 signingConfig.storeFile = storeFile 243 signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword)) 244 def storeType = props.get('storeType', props.get('key.store.type', '')) 245 if (!storeType) { 246 def filename = storeFile.getName().toLowerCase(); 247 if (filename.endsWith('.p12') || filename.endsWith('.pfx')) { 248 storeType = 'pkcs12' 249 } else { 250 storeType = signingConfig.storeType // "jks" 251 } 252 } 253 signingConfig.storeType = storeType 254} 255 256for (def func : cdvPluginPostBuildExtras) { 257 func() 258} 259 260// This can be defined within build-extras.gradle as: 261// ext.postBuildExtras = { ... code here ... } 262if (hasProperty('postBuildExtras')) { 263 postBuildExtras() 264} 265
- Cのビルド方法
- 上記のCのソースコードを作成,編集
- NDK-Buildコマンドでビルド
- 上記のandroid/src/libsフォルダ内にアーキテクチャごとに.soファイルが生成
といった順序で共有ライブラリの作成を行いました.
AndroidStudio内のjniLibsフォルダに共有ライブラリを移動したい場合は
android/src/libsに生成されたsoファイルをandroid/libsにコピーすることで
AndroidStudio内でのjniLibsフォルダにコピーが反映されます.
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/10/23 13:04
2017/10/24 00:46
2017/10/24 05:25
2017/10/24 06:30
2017/10/25 09:13