FC2ブログ

スマフォのアプリを作りたい(33):スマフォだけで動作する音声認識⑧

   プログラミング [2020/10/26]
このボヤキ・シリーズもすでに33回です。
長い。長すぎです。未だに折り返し地点も見えてきてない気がします。

久々に、作業はReactNativeの環境に戻りつつあるのですが、過去の「調べ」についてはすっかり頭から消えて、「これってなんだっけ?」の繰り返しになってます。以前の書き込みを読み返してみても、自分でも「何言ってんのかわかんない」状態。
老いなのか、地頭が悪いからか・・・


さて、このサブタイトル「スマフォだけで動作する音声認識」については、
本当にやれるのか半信半疑で始めたのですが、やっと終盤にさしかかった感じです。

ここまでで予定していた以下の段取り
Ⅰ.まずはJavaコードからC関数を呼び出すようなアプリの作り方を調べます。
Ⅱ.Javaコード(Cライブラリ含む)をReact Nativeで使えるパッケージ化方法を調べます。
Ⅲ.React Nativeにパッケージを取り込んで、Build&Go。
のⅢを始めます。

でも、未だ本当にできるかどうかは自信なしです。
やれたとしても、設計的に無理があって、Juliusさんの十分なパフォーマンスを引き出せるのかが問題。


前回の最後に書いたのですが、Ⅱの「React Nativeで使えるパッケージ化」はスキップしました。
なぜって、面倒そうだし、基本ができていないさるなので、
・ぴったり来る事例/説明が見つかりそうもない。
・お手本の説明の理解に苦労する。
・作ったものを普通に公開したいとか大それたことは思わない。
参考:https://qiita.com/TsutomuNakamura/items/f943e0490d509f128ae2

だから、パッケージ化はせずに、以前に作っていたReactNativeのプロジェクトへの単語認識用Java&C/C++ライブラリ(calljuliusライブラリ)の取り込みをやってみます。


何はともともあれ、以前VTChatとして試作していたReactNative環境近くにソース類とビルドに必要なファイルを持って行きます。
calljuliusライブラリの呼び出し元は、さるカスタマイズ版react-native-google-speech-api内のJavaコードからとなると思ってます。


◆Gradleでビルドできる環境を作る
ReactNativeも、AndroidStudioもビルドの根っこではGradleを使っています。

予想でしかありませんが、AndroisStudio環境からソースを抜き出して、Gradle(&CMake)で個別にビルドできる環境が必要なんではないだろうかと考えました。
ダウンロードして来た他のReactNative向けのパッケージがそんな感じに見えたので。

そこで最初(失敗手順)、
-「react-native-google-speech-api」の展開先フォルダ(※1)内のフォルダ/ファイル構成を闇雲に真似して作成
-「android」というサブフォルダに「src」というサブフォルダを作成して、AndroidStudioで作成したプロジェクトフォルダ中の「src」フォルダ以下まるっとコピー
-androidフォルダ直下の「build.gradle」他関連するファイルの中をちょこまか弄った
-コマンドプロンプトを開き、カレントをそのandroidフォルダにして、「gradlew compilejava」とかやって見た
まあ、上手く行くはずないですよね。(^^;)

※1:react-native-google-speech-apiパッケージは、「npm init パッケージ名」でインストールができなかったため、ZIP形式をダウンロード-展開し、それをReactNativeアプリのプロジェクト環境に組み込んだので、それに近い感じでOKではと考えてます。


「ReactNative用Javaライブラリの作り方」とかのキーワードで、かなりぐぐっては見たものの、いつも通りピッタリくる感じの解説は見つからない。
というか、少し近そうな説明はあるものの、何を言っているのかさっぱり理解できない。とほほ。
そもそも、Gradleは単なるコンパイラとかではなくビルドツールであって、build.gradleの中身はJavaっぽいGroovyという言語で書かれたスクリプトらしいけど、学習したわけではないから分かるわけない。

そんな中でも、参考にさせてもらったのは以下のサイト。
参考:https://qiita.com/NewGyu/items/c145136c256f801e1402
参考:https://blog1.mammb.com/entry/2015/04/25/020740


(1)Gradleでもプロジェクトを作成可能
「gradle init --type Javal-Library」てやると「build.gradle」のベース他ひな形環境を作ってくれるみたいです。
さっそくやって見ました。
Windows環境なので、gradleコマンドを直接たたくスベが分からなかったので、ReactNativeのプロジェクトのあっちこちにある「gradlew.bat」を使いました。
正しいやり方とは思えませんが・・・

----コマンドプロンプト-----------------------------
C:\WINDOWS\system32>cd /d d:\appmake\temp

d:\AppMake\temp>mkdir calljulius

d:\AppMake\temp>cd calljulius

d:\AppMake\temp\calljulius>mkdir android

d:\AppMake\temp\calljulius>cd android

d:\AppMake\temp\calljulius\android>\AppMake\proj\VTChat\android\gradlew --version
Downloading https://services.gradle.org/distributions/gradle-5.5-all.zip
.................................................................................................................................

------------------------------------------------------------
Gradle 5.5
------------------------------------------------------------

Build time: 2019-06-28 17:36:05 UTC
Revision: 83820928f3ada1a3a1dbd9a6c0d47eb3f199378f

Kotlin: 1.3.31
Groovy: 2.5.4
Ant: Apache Ant(TM) version 1.9.14 compiled on March 12 2019
JVM: 1.8.0_261 (Oracle Corporation 25.261-b12)
OS: Windows 10 10.0 amd64

d:\AppMake\temp\calljulius\android>
d:\AppMake\temp\calljulius\android>\AppMake\proj\VTChat\android\gradlew init --type java-library

Select build script DSL:
1: Groovy
2: Kotlin
Enter selection (default: Groovy) [1..2]

Select test framework:
1: JUnit 4
2: TestNG
3: Spock
4: JUnit Jupiter
Enter selection (default: JUnit 4) [1..4]

Project name (default: android): calljulius

Source package (default: calljulius):


> Task :init
Get more help with your project: https://docs.gradle.org/5.5/userguide/java_library_plugin.html

BUILD SUCCESSFUL in 36s
2 actionable tasks: 2 executed
d:\AppMake\temp\calljulius\android>
d:\AppMake\temp\calljulius\android>dir
ドライブ D のボリューム ラベルは Transcend です
ボリューム シリアル番号は 3E4D-1A2A です

d:\AppMake\temp\calljulius\android のディレクトリ

2020/09/11 17:29 <DIR> .
2020/09/11 17:29 <DIR> ..
2020/09/11 17:29 108 .gitignore
2020/09/11 17:29 <DIR> .gradle
2020/09/11 17:29 982 build.gradle
2020/09/11 17:29 <DIR> gradle
2020/09/11 17:29 5,917 gradlew
2020/09/11 17:29 2,942 gradlew.bat
2020/09/11 17:29 367 settings.gradle
2020/09/11 17:29 <DIR> src
5 個のファイル 10,316 バイト
5 個のディレクトリ 947,452,710,912 バイトの空き領域

d:\AppMake\temp\calljulius\android>
---------------------------------------------------

-大元のプロジェクトフォルダ(calljulius)を作成
-さらにその下にandroidフォルダを作成
-ReactNativeのプロジェクト下にあるgradlew.batを使って、Gradleのバージョンを表示
※環境変数(GRADLE_HOME)を設定していないからか?Gradle5.5をダウンロードしてインストールしちゃったみたいです。
-プロジェクトの初期化「gradlew init --type java-library」を実行
-フォルダの中に「build.gradle」他ファイル、フォルダが作成されているのを確認
※「android\src\main\java\calljulius」の下には、「Library.java」というソースも作られていました。

なんだか、この状態でビルドできそうな感じがしたので、やってみました。
----コマンドプロンプト-----------------------------
d:\AppMake\temp\calljulius\android>gradlew compilejava --info
Downloading https://services.gradle.org/distributions/gradle-5.5-bin.zip
.....................................................................................
Initialized native services in: C:\Users\sarumosunaru\.gradle\native
The client will now receive all logging from the daemon (pid: 10692). The daemon log file: C:\Users\sarumosunaru\.gradle\daemon\5.5\daemon-10692.out.log
Starting 3rd build in daemon [uptime: 7 mins 24.971 secs, performance: 99%, non-heap usage: 14% of 268.4 MB]



Task ':compileJava' is not up-to-date because:
No history is available.
All input files are considered out-of-date for incremental task ':compileJava'.
Full recompilation is required because no incremental change information is available. This is usually caused by clean builds or changing compiler arguments.
Compiling with JDK Java compiler API.

> Task :compileJava FAILED
:compileJava (Thread[Execution worker for ':',5,main]) completed. Took 14.938 secs.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_261 contains a valid JDK installation.


BUILD FAILED in 1m 11s
1 actionable task: 1 executed

d:\AppMake\temp\calljulius\android>
---------------------------------------------------

-ビルド「gradlew compilejava --info」を実行
※今度は、「gradle-5.5-bin.zip」をダウンロードして組み込んだ模様。???(バージョンを調べたときはgradle-5.5-all.zip)
実際に「C:\Users\(ユーザID)\.gradle\wrapper\dists」下に展開されたフォルダが2つ作成されていました。
ReactNative配下で使用しているものとは別なはずなので、後で消してもいいのかな?
→結局、ビルドはエラーで終了。


続きます。


-ちょっと脱線:ビルド環境に対するボヤキ-
今更なのですが、Gradleの実体って何なんでしょうか。
インストールされた「gradle-5.5-all」と「gradle-5.5-bin」のフォルダの中を見てみました。
bin/libの内容は、ほぼ一緒の構成に見えました。

「bin」サブフォルダの中には、「gradle」(シェルスクリプト?)、「gradle.bat」(バッチファイル)しかありません。
「lib」サブフォルダの中には、沢山の.jarファイルがあって、「gradle-xxx.jar」というのも結構あります。
こっちが処理を行う実態なんじゃないだろうか。つまりJavaで動くもの?

「C:\Users\(ユーザID)\.gradle\wrapper\dists」には「gradle-6.1.1-all」フォルダもあって、こっちは日付をみるとVisualStudio利用中にインストール(Upgrade)されたもののようです。

元々、「react-native run-android」ってやってた時のGradleの環境はどこにあるのか?
「Android Studio\plugin」の下にも「gradle\lib」等のフォルダがあり、「(プロジェクトフォルダ)\android\gradle\wrapper」もありました。
これ?・・・いまのところ、はっきり理解できてません。

似たようにアッチコッチに環境があるという点では、前述したビルドエラーにもなっている「jre」にも言えます。
Windowsの[設定]-「アプリ」-「アプリと機能」では、「Java 8 Update 261 (64-bit)」と「Java SE Development Kit 8 Update 231 (64-bit)」と二つインストールされていることになっており、「C:\Program Files\Java\jre.1.8.0_261」と「D:\・・・\Java\jdk1.8.0_231」がありました。また、「Android Studio\jre」というフォルダもありました。
(ビルド番号?)261の方がJava動作環境(JRE)で、231の方は開発環境(JSE/JDK)で違うものなのかとは思いますが、ちょっと紛らわしいのでイラつきます。
開発環境としては、ReactNativeの環境構築時にインストールしたもので、AndroidStudio下のものはバンドルされている環境なんでしょう。
でも、似て非なるものは、ディスク容量を食うだけなので、インストーラが勝手に差分だけアップデートして一か所に統合してくれるといいんですけどね。



さて、ボヤキが長くなりましたが、ビルドエラーは、JREの環境を参照しにいっちゃってます。本来はJSE/JDK側を参照するべきです。
同様のエラーに関しての書き込みがあったので、それを参考にしました。

-作成したフォルダ(calljulius\android)にgradle.propertiesファイルを新たに作成し、以下の1行を書き込み
----gradle.properties---------------------------
org.gradle.java.home=D:\\AppMake\\Java\\jdk1.8.0_231
---------------------------------------------------

-再度gradlew compilejava --infoを実行
→正常にテンプレートがビルドされました。


(2)テンプレートにJuliusLibライブラリを上書き
参考:https://www.tuyano.com/index2?id=5688424874901504
参考:https://qiita.com/hatimiti/items/a127311d739c9d3e0045
参考:http://gradle.monochromeroad.com/docs/

(2-1)AndroidStudioで作成した「JuliusLibをコールするためのライブラリ環境」から「(プロジェクトフォルダ)\app\src」の中身を(1)で作成した「calljulius\android\src」の下にまるっとコピーしました。
→Gradleのテンプレート(gradle initで作成作成された)build.gradleではビルドできるはずもありません。(やってみたけどね。)

(2-2)AndroidStudio環境下の2つのbuild.gradleを合体させたbuild.gradleを作成してみた。
やっぱり、build.gradleの中に書かれている内容の意味は、この時点でも全く理解できてません。
内容はこんな。(全てcalljulius\androidフォルダの下に作成しています。)

----settings.gradle--------------------------------
//include ':app'
rootProject.name='calljulius'
---------------------------------------------------

※appというフォルダは無くなっているので「include・・・」はコメントアウトしました。

----gradle.properties------------------------------
# JDK path
org.gradle.java.home=D:\\AppMake\\Java\\jdk1.8.0_231
# org.gradle.jvmargs=-Xmx1536m

android.useAndroidX=true
android.enableJetifier=true
---------------------------------------------------

※(1)で追加した記述に、AndroidStudio環境下で指定されていた内容を持ってきてます。ただし、「org.gradle.jvmargs=・・・」はなんとなくコメントアウト。

----local.properties-------------------------------
sdk.dir=D\:\\AppMake\\Android\\Sdk
---------------------------------------------------

※gradle.propertiesのorg.gradle.java.homeのときのパスの書き方が違っていることに注意。なんで違うの?

----src\main\androidManifest.xml-------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.teburarec.calljulius">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:extractNativeLibs="true">
<!--
<activity android:name="com.teburarec.calljulius.JlibGate">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
-->

</application>

</manifest>
---------------------------------------------------

※「<activity・・・」は要らないみたいです。あるとエラーになりました。

----build.gradle-----------------------------------
//AndroidStudioのプロジェクト直下のbuild.gradleの内容
//基本的なビルド環境の指定?
buildscript {
repositories {
google()
jcenter()

}
dependencies {
//最小バージョンを示す。
//4.0.0→Gradle V6.1.1、Gradle5.5環境下ではバージョンエラー。3.4.0→Gradle V5.1.1
//classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:3.4.0'


//「ここにビルド対象のdependenciesを書いてはいけない。」とのコメント有り
}
}

//この記述もないとエラーになってました。
allprojects {
repositories {
google()
jcenter()

}
}

//AndroidStudioのプロジェクト\app下のbuild.gradleの内容
//ビルドのためのベースライブラリの指定
apply plugin: 'com.android.library'

android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
buildTypes {
debug {
debuggable true
minifyEnabled false
jniDebuggable true
renderscriptDebuggable true
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
ndkVersion '21.3.6528147'
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

/*
//AndroidStudioのプロジェクト直下のbuild.gradleの内容
//'android'プロジェクトに同じ名前('crean')が既にあるらしいのでエラーになる
task clean(type: Delete) {
delete rootProject.buildDir
}
*/


/*
//gradle initで作成された内容
apply plugin: 'java-library'

repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}

dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'

// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:27.1-jre'

// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
*/

---------------------------------------------------

※※「.gradle」はスクリプトの類だからかコメントは「//」か「/*・・・*/」で、「.properties」は設定ファイルの類だからかコメントは「#」。
わからんではないが、紛らわしい。


上記のGradle関連の指定にたどり着くまでに1週間ほどの期間、迷走しました。
ここまでやってしまうと、「Gradleのテンプレートに上書き」したというよりは、「AndroidStudioの環境をそのまま持ってきた」と言う方が正しいですね。
つまり、最初に試したことの延長で、(1)の手順は意味がなかった気がします。


これで、「gradlew build」とやってビルドが通ることは確認できました。
がしかし、作成されたのは、やっぱり「.jaa」ファイル。



◆.jaaと.jarファイルの違い
build.gradleの記述のどこが、出力として.jarと.jaaを切り替えているのか散々ググったり、build.gradleの記述を眺めてみましたが、「gradlew init --type java-library」で作成されたbuild.gradleとAndroidStudio側で作られたそれとでは内容が違い過ぎてて、結局分かりませんでした。
aplly plugin: 'com.android.library'」の中にその正体があるとは想像するものの、今の自分の実力で中身を見て解読できるとは到底思えない。

当初から見ていたAndroidStudio上でのライブラリ作成について説明しているページによれば、
AndroidStudioの[File]-「New」-「New Module...」で新規に「Java Libraryを作成すると、ビルド結果として「.jarが作成される」とあったので、その環境のbuild.gradleの中身を今のjaa出力用のbuild.gradleと比較すれば、その違いが見つかるかもしれないと思ってやってみた。

AndroidStudio4.0の選択画面上では、「Java or Kotlin Library」となっているので要注意です。
現にさるの場合、「Java Library」と「Android Library」を混同してしまい、しばらく「Android Library」を選択して試していました。 そのため「何で.jaaしか作られないのよー?」としばらく行き詰ってしまった。


結果としては、「Java Library」作成環境のbuild.gradleの中では、pluginされるのが「'java-library'」になります。
たぶんこの違いが、.jaaを作成するパターンと.jarを作成するパターンの違いではないかと予想します。

さて、ここに辿り着くまでに気が付いたのが、「Android Library」でもビルド時に「classes.jar」というファイルが作られているということです。

では、この.jarと.jaaの中身の違いは・・・

両者とも実態は圧縮ファイルのようで、Windows上では、右クリックして「解凍」を選択すると、解凍されて中身を見ることができます。ちなみに、
.jarファイルは、パッケージ名になっているフォルダ階層の下に.classファイルが含まれているのみで、
.jaaファイルは、classes.jarを含んでさらにAndroidManifest.xml、R.txt、assetsフォルダ、jniフォルダ(.soを含む)、およびその他のcpu毎のフォルダなどがありました。

ここまで書いた内容って、Android/Java開発の環境では、常識中の常識なんでしょうね。
「ちゃんと、(どっかの)説明読めよ!」って、言われるオチなんだろうな~。


でも、現実にはそういう学習を経ないでやってるので、
・.jarはどこに出力させるのが常識的なのか?
・ReactNativeでは、.jarで依存関係のJavaライブラリ部を取り込むのみななのか?
・だとすれば、C/C++ライブラリ(.so)とその関連ファイル(assetsの中身)はどうやって?
と、まだまだ疑問が尽きません。


◆react-native-google-speech-apiからの依存関係
前述の最後の3つの不明点はあるものの・・・
「ract-native run-android」とやった時に、react-native-google-speech-apiと共にビルドされて、calljuliusライブラリに含まれるjuliusword.so(assetフォルダに含まれる環境一式も含む)がアプリのAPKに組み込まれるにはどうするのかを調べつつ、カットアンド・トライしていきます。

-ちょっと余談:google-speech-apiが孤児に-
ところで、この記事書き始めてからreact-native-google-speech-apiのダウンロード元のGitHubを参照してみたら・・・
ページ(https://github.com/KWRI/react-native-google-speech-api)が無くなってる!!!
もう一つの別のページ(同名パッケージ提供元)はまだありました。
そもそも、「npm install react-native-google-speech-api」でエラーになってた代物なので、不安です。
今後はアップグレードもされないってことになりますね。根本的な問題でもあったんでしょうか。
嫌な予感。でも、もっと後で悩むことにしてこの件はスキップします。


まずは、react-native-google-speech-apiのandroid\build.gradle内の「dependencies{}」にcalljuliusライブラリを追加する必要がありそうです。
参考:https://developer.android.com/studio/build/dependencies


(1)ローカルライブラリ モジュールへの依存関係としてお試し
上記ページに記載されている「ローカルライブラリ モジュールへの依存関係」がなんだか一番シックリする感じに思えた。

でも、説明を読んでいて分からないのが、フォルダ構成です。
ローカルライブラリをimplementationする場合、「settiongs.gradleのincludeで設定している名前と一致する必要がある」と書いてます。
じゃあ、その名前のライブラリはどこに配置すればいいのかが書かれてない。
AndroidStudioを使うことを前提にしているから知る必要はないってことなのか?でも、書いてくれよ!

仕方ないので、Android]Studioを起動して、元のcall_juliusプロジェクトを開いて、再度「Java Library」モジュールを追加し、その結果でどういうフォルダ構成が追加されるかとsettings.gradleやらbuild.gradleの記述がどう変化するか見てみた。

・追加ライブラリモジュール(myjavalib)のフォルダは、「(プロジェクトフォルダ)\app」と同じ並びに作成された。
・プロジェクトフォルダ直下のsetting.gradle内に「include ':myjavalib'」行が追加されていた。
・ただし、app\build.gradle内に「dependencies {・・・implementation project(":myjavalib")・・・}」とは追加されていなかった。「そこは手で修正しろ」ということなのだと解釈。

上記を真似してやってみました。
----フォルダ構成-----------------------------------
<react-native-google-speech-api>
 ├<android>
 │ ├<.gradle>
 │ ├<build>
 │ ├<gradle>
 │ ├<src>
 │ ├build.gradle
 │ ├gradlew
 │ ├gradlew,bat
 │ ├setting.gradle ・・・・追加1
 │ ├gradle.properties ・・・追加2
 │ └<calljulius> ・・・・追加(calljulius\android以下をコピー)
 │   ├<.externalNativeBuild>
 │   ├<.gradle>
 │   ├<builde>
 │   ├<gradle>
 │   ├<libs>
 │   ├<release>
 │   ├<src>
 │   ├.gitignore
 │   ├build.gradle
 │   ├gradle.properties
 │   ├gradlew
 │   ├gradlew.bat
 │   ├local.properties
 │   ├settings.gradle
 │   :
 :
---------------------------------------------------

----追加1:build.gradle---------------------------


dependencies {
 :
 :
//# calljulius
implementation project(":calljulius")

}
---------------------------------------------------

----追加2:settings.gradle------------------------
include ':calljulius'
---------------------------------------------------

----追加3:gradle.properties----------------------
# JDK path
org.gradle.java.home=D:\\AppMake\\Java\\jdk1.8.0_231
---------------------------------------------------


「react-native-google-speech-api\android」をカレントにして「gradlew build」を実行してみた。
----コマンドプロンプト-----------------------------
:
> Task :compileDebugJavaWithJavac
D:\AppMake\temp\react-native-google-speech-api-master\android\src\main\java\com\reactlibrary\GoogleSpeechApiPackage.java:12:
エラー: GoogleSpeechApiPackageはabstractでなく、ReactPackage内のabstractメソッドcreateJSModules()をオーバーライドしません
public class GoogleSpeechApiPackage implements ReactPackage {
:
---------------------------------------------------

「calljuliusプロジェクトがない」というエラーは出なかったが、
「ReactPackage内abstructメソッドをオーバーライドしてない」というエラーが出てしまいました。
今回の修正の入っていないオリジナルな状態でも出てたエラー。
そもそも、パッケージ毎ビルドって単独で通るようになっていないもの?

なので、上記エラーは一旦ほっぽって、別のコマンドプロンプトで
(取り込み先ReactNativeプロジェクトの)「react-native run-android」を実行してみた。
----コマンドプロンプト-----------------------------

* What went wrong:
A problem occurred evaluating project ':react-native-google-speech-api'.
> Project with path ':calljulius' could not be found in project ':react-native-google-speech-api'.

---------------------------------------------------

こっちは、「calljuliusプロジェクトがない」というエラー。

参考:http://gradle.monochromeroad.com/docs/userguide/build_lifecycle.html
参考:http://gradle.monochromeroad.com/docs/userguide/multi_project_builds.html

上記のGradleの解説ページをだいぶ時間を掛けて読んだけど、やっぱ余り理解できない。
どうもsettings.gladleはGradleの初期化フェーズで読み込まれて(実行される)もので、マルチプロジェクト対応のときでもルートプロジェクトのものだけが有効になるように読める。サブプロジェクトが単独でビルドできるようにsettings.gladleファイルを持っていたとして、それも初期化フェーズで取り込めるような記述はどこにもない。

ちなみに、「react-native run-android」でGradleを実行フォルダにある(1)settings.gradeとreact-native-google-speech-apiプロジェクトにある(2)settings.gradeをそれぞれ以下のようなステートメントを追加して、「react-native run-android」を実行してみると、(1)側のprintln出力だけが表示されました。
----settings.gradle(1)-----------------------------
rootProject.name = 'VTChat'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'

//# Test statement to understand the effect of this file.
println '%%%%%%% VTChat settings.gradle conditions %%%%%%%'
println 'root dir: ' + rootProject.projectDir
println 'react-native-google-speech-api: ' + project(':react-native-google-speech-api').projectDir
---------------------------------------------------

----settings.gradle(2)-----------------------------
include ':calljulius'

//# Test statement to understand the effect of this file.
println '%%%%%%% RN-google-speech-api settings.gradle conditions %%%%%%%'
println 'root dir: ' + rootProject.projectDir
println 'calljulius: ' + project(':calljulius').projectDir

---------------------------------------------------


んーー。
なんか解せない話です。
パッケージとして取り込むプロジェクト(子)内にサブプロジェクト(孫)があって、そのパッケージ・プロジュエクト(子)内の依存関係を有効にするためには「settings.gradleでのinclude設定が必要だ」となっているのに、「パッケージとして取り込んだ場合、その孫プロジェクトに当たるinclude設定を取り込んだ先の親のsettings.gradleに仕込まないといけない」ということになってしまいます。パッケージ化としての考え方が変というか、そんな不便があるのかな。

解せないので、さらに調べます。
ReactNativeプロジェクトのandroid\settings.gradleの中には、「apply from: ・・・; applyNativeModulesSettingsGradle(settings)」という記述があって、その「applyNativeModulesSettingsGradle(settings)」がなんか怪しい。

参考:https://www.finddevguides.com/Gradle-plugins
上記によると、「apply from: '・・・'」という記述は、スクリプトプラグインと呼ばれるもので、他の.gradleスクリプトをプラグインするためのものだそうです。
ですが、その後の「; applyNativeModulesSettingsGradle(settings)」は?

この書き方の意味やapply・・・メソッドの「効能」についての説明が発見できません。唯一
参考:https://qiita.com/tkow/items/67509d4527d0536474da
このサイトにこんな記述がされていました。
『ネイティブモジュールを作成する際はreact-naive-から始まるjsパッケージを追加し、projectのsettings,gradleとbuild.gradleの設定を定義するだけでnaive moduleとして読み込まれるようになります。』
途中の「projectの」が親(ルート)プロジェクトを意味するのか、パッケージ化されたreact-native-プロジェクトのことを指すのか明確ではありませんが、都合良く解釈すれば後者です。そうなれば、react-natove-google-speech-apiに加えた修正(ライブラリモジュールcalljuliusの追加)は、そのルールに即して有効になるハズ。

でもそうなってない。
(リンク先ページのスクリプト自体を読まないといけないのか?!)
んーーーーー。
フン詰まってしまいました。


こっちのやり方は一時停止して(2)を検討しましたが・・・
またまたフン詰まってしまったので、このやり方を継続カットアンドトライを続けて見ました。


なんか、子プロジェクトのsettings.gradleを取り込めない点に納得いってないのですが、
ルートプロジェクトのsettings.gradleに孫プロジェクトの「include ':calljulius'」を追加して「react-native run-android」を実行してみます。
単に「include ':calljulius'」しただけでは、当然うまくいくわけもなく、
記述は以下のようにする必要がありました。
----settings.gradle(1)-----------------------------
rootProject.name = 'VTChat'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app', ':calljulius'
project(':calljulius').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-speech-api/calljulius')


//# Test statement to understand the effect of this file.
println '%%%%%%% VTChat settings.gradle conditions %%%%%%%'
println 'root dir: ' + rootProject.projectDir
println 'react-native-google-speech-api: ' + project(':react-native-google-speech-api').projectDir
---------------------------------------------------


次に、よくわかんないんだけど、「・・・・\fonts」がアクセスできないというエラーがガーっと出ました。
フォルダが無かったみたいなので、エクスプローラで作成してやりました。

その次、
----コマンドプロンプト-----------------------------
D:\AppMake\proj\VTChat>react-native run-android


D:\AppMake\proj\VTChat\android\app\src\debug\AndroidManifest.xml:12:7-34 Error:
Attribute application@allowBackup value=(false) from AndroidManifest.xml:12:7-34
is also present at [:calljulius] AndroidManifest.xml:12:9-35 value=(true).
Suggestion: add 'tools:replace="android:allowBackup"' to element at AndroidManifest.xml:7:5-117 to override.

D:\AppMake\proj\VTChat\android\app\src\debug\AndroidManifest.xml Error:
uses-sdk:minSdkVersion 21 cannot be smaller than version 23 declared in library [:calljulius] D:\AppMake\proj\VTChat\node_modules\react-native-google-speech-api\calljulius\build\intermediates\library_manifest\debug\AndroidManifest.xml as the library might be using APIs not available in 21
Suggestion: use a compatible library with a minSdk of at most 21,
or increase this project's minSdk version to at least 23,
or use tools:overrideLibrary="com.teburarec.calljulius" to force usage (may lead to runtime failures)

:
:
---------------------------------------------------


一つ目のエラーは、マニフェスト中の「allowBackup=」※指定が、ルートプロジェクト(VTChat)と孫プロジェクト(calljulius)で不一致だと言ってる感じです。
※アプリ動作時の自動バックアップの指定?
なので、calljulius側のマニフェスト(rect-native-google-speech-api\calljulius\src\main\AndroidManifest.xml)の指定をtrueからfalseに変更しました。
----AndroidManifest.xml----------------------------

package="com.teburarec.calljulius">

android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
:
:
---------------------------------------------------

二つ目のエラーは、build.gradle中に指定されている「minSdkVersion=」がルートプロジェクトより孫プロジェクトの方が新しいということかと。
孫の方が古い分には、OKらしい?
なので、この件に関しては、ルートプロジェクトの「android\build.gradle」内指定を更新しました。
----build.gradle-----------------------------------
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext {
buildToolsVersion = "28.0.3"
//*** changed min_version for google-speech-api by sarumosunaru
//minSdkVersion = 16
//minSdkVersion = 21 //...not available with calljulius
minSdkVersion = 23

compileSdkVersion = 28
targetSdkVersion = 28
}
:
:
---------------------------------------------------

「react-native run-android」の先でcalljuliusのビルドが走りました。
※以下の(2)は読み飛ばしてください。本当に単なるボヤキです。


(2)リモートバイナリへの依存関係としてお試し・・・断念
----フォルダ構成-----------------------------------
<react-native-google-speech-api> ・・・(元の構成のまま)
<react-native-calljulius>    ・・・(フォルダ名をcalljuliusから変更)
 ├index.js
 ├package.json
 ├<android>
 │ ├<.externalNativeBuild>
 │ ├<.gradle>
 │ ├<builde>
 │ ├<gradle>
 │ ├<libs>
 │ ├<release>
 │ ├<src>
 │ ├.gitignore
 │ ├build.gradle
 │ ├gradle.properties
 │ ├gradlew
 │ ├gradlew.bat
 │ ├local.properties
 │ ├settings.gradle
 │ :
 :
---------------------------------------------------

フォルダ名を変更して、package.json内の「"name"」もそれに合わせて変更しました。
なんか嘘くさい。
次に、「・・・google-speech-api」側のbuyild-gradleのdependenciesを変更しました。
----追加1:build.gradle---------------------------


dependencies {
 :
 :
//# calljulius
//implementation project(":calljulius")
implementation 'com.teburarec.calljulius:JlibGate:0.0.1'

}
---------------------------------------------------

上記では適当(いいかげん)に書いちゃってますが、
リモートバイナリの依存関係を記述する場合、本来の内容は、「implementation 'group:name:version'」なんだそうです。
でも、それら(group/name/version)はどこで定義しているもの?
分かりません。最初の段階で躓いてます。
package.json? .java内のpackage記述? AndroidManifest.xml?・・・
散々検索しまくりましたが、ぴったりくる説明がどーしても見つかりません。
なんでー?肝心なところを説明してくれてないのー。
このモヤモヤで、2週間くらい足踏みしてしまった。

上記の状態で「npm install raect-native-calljuliusのパス」を実行して、
ビルド(run-android)させてみても、やっぱり依存関係のものが見つからないとエラーが出ます。
そりゃそうだわな。
(プロジェクトフォルダ)\node-modules\react-native下の.jarを探しに行ってるみたいです。
raect-native-calljuliusのビルドを走らせてるフシはない。

悩んだ挙句、結局(1)に戻って、そっちの調べを続けることにしました。



この段階でこんなに時間がかかるとは予想しなかった。
これまでも、React Nativeの環境は混沌としているというか、
何しろ関わってくるツール類が多くてかつ情報が分散しすぎている
と・・・(自分のことは棚に上げて)そう思う。

紆余曲折を全部書いてあるので、長ーくなったので、あともうちょっと?のはずなんだけど、一旦ここで話を切ります。

たぶん誰も最後まで読んでないとは思いますが、
この回はこの辺で。御機嫌よう。
m(?_?)m
スポンサーサイト





コメントの投稿

非公開コメント

カレンダー
01 | 2024/02 | 03
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 - -
プロフィール

さるもすなる

Author:さるもすなる
さるです。別HPサイト「さるもすなる」から侵食してきました。 山菜/きのこ、それとタイトルにしたPPバンド籠のことをメインに徒然に・・・・暇を持て余したさるの手仕事:男手芸のブログってことで。

最新記事
最新コメント
月別アーカイブ
カテゴリ
天気予報

-天気予報コム- -FC2-
本家のHPのトップ
山菜や茸の話です
PPバンドの籠作品と作り方です
投稿をお待ちしております



PVアクセスランキング にほんブログ村 にほんブログ村 ハンドメイドブログへ



マニュアルのお申し込み



検索フォーム
リンク
RSSリンクの表示
ブロとも申請フォーム

この人とブロともになる

QRコード
QR