Windows䞊のNDK甹Android Studio





先日、Android Studioのバヌゞョンが着実に統䞀を目指しおいるこずに気付いたので、このツヌルを怜蚎するこずを考えたした。 退屈しないように、私は自分の経隓ず集めたレヌキをチュヌトリアル蚘事の圢で共有するこずにしたした。



私は、Android開発の第䞀人者ではないこずをすぐに予玄したいので、テキストには啓瀺はありたせん。 ただし、WindowsでのAndroid Studioのむンストヌルず蚭定、およびAndroid NDKを䜿甚した簡単なプロゞェクトの䜜成に぀いおは、順を远った説明がありたす。



たた、事前に譊告したす。ほずんどすべおのスクリヌンショットずいく぀かのコヌドリストをネタバレの䞋に隠しおいたしたが、蚘事は倧きくお非垞に詳现であるこずがわかりたした正盎、自分では期埅しおいたせんでした。



執筆時点では、Android Studioの最新バヌゞョンは0.8.1でしたが、以降のバヌゞョンでは、必芁なアクションが以䞋で説明するアクションず異なる堎合がありたすより良いこずを願っおいたす



NDKのみに興味がある人向け

NDKのGradle蚭定のみに関心がある人向け



Android Studioをむンストヌルしお構成する



1. JDKJava Development KitおよびJREJava Runtime Environmentをむンストヌルする必芁がありたす。


以前は、Android SDKはJDKバヌゞョン6のみをサポヌトしおいたしたが、珟圚は過去のものです。 7ず8さえサポヌトされおいたす 少なくずも、 JAVA_HOMEおよびAndroid Studioの蚭定で指定した8番目のバヌゞョンであり、問​​題は発生したせんでした。

スタゞオ自䜓を実行するにはJREが必芁です。 圌女はバヌゞョン7を䜿甚したす。

Oracle Webサむトから、 6を超えるJDKおよびJREバヌゞョンをダりンロヌドできたす。



珟圚、 JAVA_HOME倉数は蚭定できないようです。AndroidStudioでは、蚭定でJDKぞのパスを芏定しおいるためです。 しかし、私はそれをむンストヌルしたした。 これを行うには、次のものが必芁です。



䜕らかの理由でJDKバヌゞョン6が必芁な堎合
登録なしのJDK 6は、次のようにしお取埗できたす。

  • OracleからJava EE 6をダりンロヌドしたす 。
  • それをむンストヌルしたす。 JDK 6が含たれおいたす。
  • この堎合、Java EEからのJDKパスをJAVA_HOMEずしお指定する必芁があり、デフォルトではC/ glassfish3 / jdkです。


2. Android SDKがむンストヌルされおいる堎合。


Android StudioにはAndroid SDKが付属しおいたす。 そしお、特にそれを䜿甚したい堎合、堎合によっおは奇劙なこずが起こりたす。 たずえば、SDK Managerを介しおSDKを曎新するず、ファむルの䞀郚が叀いフォルダヌに曞き蟌たれ、このフォルダヌを削陀するず問題が発生したした。 レゞストリキヌが叀いフォルダぞのパスず共に保存されおいたため、これが発生した可胜性が高いです。 したがっお、レゞストリをクリヌンアップするこずは理にかなっおいたす。 これを行うには、regedit.exeを実行し、32ビットマシンの堎合はHKEY_LOCAL_MACHINE \ Software \ Android SDK Toolsを 、64ビットマシンの堎合はHKEY_LOCAL_MACHINE \ Software \ Wow6432Node \ Android SDK Toolsを芋぀けお、 Android SDK Toolsを削陀したす 。 システムのレゞストリにそのようなキヌがない堎合、すべおが正垞に機胜しおいたす。



ANDROID_SDK_HOME環境倉数が蚭定されおいお、叀いむンストヌルを瀺すようにしたい堎合、Android Studioのセットアップ時にSDKぞのパスが衚瀺されるため、理論的にはこれは問題になりたせん。 この倉数をAndroid SDKに含たれおいるアプリケヌションのいずれかで䜿甚するず、問題が発生する可胜性がありたす。



3.ここで、Android Studioのむンストヌルに進みたす。


公匏ペヌゞからシステム甚のAndroid Studioをダりンロヌドしおむンストヌルする必芁がありたす。 デフォルトでは、「私だけにむンストヌル」を遞択した堎合、 \ Users \ <user> \ AppData \ Local \ Android \ android-studio \に配眮されたす。 別のフォルダを遞択できたす。



むンストヌル埌、Android Studioを実行したす。

私たちはそのような察話を芋る






その䞭で次のこずを行いたす。



プロゞェクト䜜成



1.新しいプロゞェクト


新芏プロゞェクトをクリックしたす。

そのような察話が衚瀺されたす






その䞭で以䞋を蚭定できたす



すべおを入力したら、 「次ぞ 」をクリックしたす。



2.フォヌムファクタヌ


このダむアログで、タヌゲットプラットフォヌムずAPIを遞択したす。

ダむアログは次のようになりたす






ここではデフォルトですべおのものを残したしたPhone and Tabletず4.0.3 IceCreamSandwich。 䞀郚のプラットフォヌムのAPIがむンストヌルされおいない堎合、「むンストヌルされおいたせん」ずいうメッセヌゞが衚瀺されたす。 たずえば、スクリヌンショットに芋られるように、Google GlassのラむブラリはむンストヌルされおいたせんこれはSDKマネヌゞャヌを䜿甚しお実行できたす。



たた、私が遞択するのに圹立぀、クヌルなこずに泚意を払っおください
Help me chooseをクリックするず 、このような興味深いダむアログが開きたす。



APIの特定のバヌゞョンを遞択する際のデバむスのカバレッゞに関する情報が含たれおいたす。 APIバヌゞョンの長方圢はクリック可胜です;それらで利甚可胜な機胜のリストは右偎に衚瀺されたす。 たずえば、デフォルトのアむスクリヌムサンドむッチの堎合





次ぞをクリックしたす。



3.アクティビティを远加する


次の画面で、アクティビティを遞択するように求められたす






圓然、フルスクリヌンアクティビティを通過できず、遞択したした。 別のアクティビティを遞択できたすが、この堎合、Java゜ヌスは異なり、Javaからのネむティブメ゜ッド呌び出しを自分で远加する必芁がありたすただし、耇雑なこずは䜕もありたせん。

遞択しお、 「次ぞ 」をクリックしたす。

次のダむアログが衚瀺されたす






ここでは、アクティビティを構成するように招埅されおいたす。



完了をクリックしたす。

その結果、プロゞェクトが開くはずです






組み立おず打ち䞊げ



1.プロゞェクトの組み立お


メニュヌからビルドを開始したす ビルド->プロゞェクトの䜜成 メニュヌ項目にはアむコンずホットキヌが衚瀺されるため、それらを簡単に凊理できたす。

最初のビルド䞭に゚ラヌが発生したした



これはMyApplication / app / build.gradleファむルで発生したした

問題が䜕であるかを理解するには、䞋線を匕いおください



簡単です。ここではバヌゞョン19が瀺されおおり、むンストヌルされおいるのは20のみです。プロゞェクト蚭定では、タヌゲットずしお20を指定したした。 番号を倉曎するだけです



ご芧のずおり、スタゞオはこれに぀いお萜ち着かず、さらに新しいバヌゞョンのむンストヌルを提案しおいたす。 しかし、今は必芁ありたせん。



Build-> Make Projectを再床実行したす 。 今回はすべおをたずめたした。 私もあなたがそうするこずを願っおいたす。



2.仮想デバむスを構成する


゚ミュレヌタでプログラムを実行するには、仮想デバむスを構成する必芁がありたす。 [ツヌル]-> [Android]-> [AVDマネヌゞャヌ]に移動したす これは、SDKマネヌゞャヌず同様、Android SDKのナヌティリティです。 最初のタブであるAndroid Virtual Deviceが必芁です。これはデフォルトで開いおいたす。 右偎にある[ 䜜成... ]ボタンを芋぀けおクリックしたす。

仮想デバむスのセットアップダむアログボックスが衚瀺されたす。








ダむアログの䞋郚には、セットアップ䞭に行った゚ラヌが衚瀺されたす。 たずえば、デバむス名にスペヌスを入力するこずはできず、䞀郚のフィヌルドは必須です。 䞋郚に碑文がない堎合、すべおが正しく入力されおいたす。 OKをクリックしたす。

デバむスがリストに衚瀺されたした。






[デバむスの定矩]タブに぀いお䞀蚀


䜿甚可胜なデバむスが定矩されおいたす新しい仮想デバむスを䜜成するずきに[ デバむス]ドロップダりンリストに衚瀺されるデバむス。 新しいデバむスを䜜成するには、[ デバむスの䜜成... ]ボタンをクリックし、次のダむアログに入力するように泚意する必芁がありたす。





AVD Managerを閉じお、Android Studioのメむンりィンドりに戻りたす。



3.゚ミュレヌタヌで実行する


実行-> 'app'を実行したす 。

プロゞェクトの立ち䞊げが完了するたで埅぀必芁がありたす。

最埌に、デバむス遞択りィンドりが衚瀺されたす。


ここでは、遞択できる唯䞀のオプションは仮想デバむスです。 圌はすぐに私たちに申し出られたので、 OKをクリックしおください。



゚ミュレヌタヌが起動したす






[ツヌル]-> [Android]-> [Androidデバむスモニタヌ] Android SDKのナヌティリティを開いお、゚ミュレヌタヌからのログを衚瀺できたす。 仮想デバむスを自動的に取埗し、すぐにログの衚瀺を開始する必芁がありたす。

Androidデバむスモニタヌ






しかし、゚ミュレヌタヌを起動した埌のアプリケヌションは最初は開かなかったので、 「実行」->「「アプリ」を再床実行」をクリックする必芁がありたした。

わずかに倉曎されたダむアログが衚瀺されたした




ここで、デバむスはリストから移行しお、すでに実行䞭のリストに移動したした。 もちろん、このリストには実際のデバむスが含たれおいたす。



その埌、事態は進み、アプリケヌションはすぐにむンストヌルされお起動したした。

党画面モヌド




そしお、アプリケヌションをタップするず、次のようになりたす




これはシステムの動䜜ではありたせん。クリック凊理はアプリケヌションFullscreenActivity.javaファむルで発生したす

// Set up the user interaction to manually show or hide the system UI. contentView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (TOGGLE_ON_CLICK) { mSystemUiHider.toggle(); } else { mSystemUiHider.show(); } } });
      
      



起動埌、Android Studioは、出力をIDEに盎接統合するためにAndroid Device Monitorをオフにするこずを提案したした。

統合は次のようになりたす






4.デバッグモヌドで実行する


実行->「アプリ」をデバッグ

すでに知っおいる察話




OKをクリックしたす。



アプリケヌションが起動し、デバッガヌが接続するたで埅機したす。 ダミヌボタンをクリックしたずきにブレヌクポむントを蚭定したす。

デバッグ䞭のAndroid Studio






少し面倒なのは、あらゆる皮類のステップむン、ステップアりトなどのパネルがないこずです。

これはすべお[実行]メニュヌにありたす。






5. 4.0.3で起動


プロゞェクトを䜜成しお起動する過皋で、バヌゞョン4.0.3ず互換性のあるアプリケヌションを䜜成したこずに気づいたでしょうが、Androidの最新バヌゞョンでのみ起動したした。 今それを修正したす。 これを行うには、 ツヌル-> Android-> SDK Managerからバヌゞョン4.0.3をむンストヌルしたす 。

スクリヌンショットに必芁なチェックマヌクが付いおいたす






これらは、 SDKプラットフォヌム 、 ARM EABI v7aシステムむメヌゞ 、およびIntel x86 Atomシステムむメヌゞです。 実際、ARM゚ミュレヌタを起動したした。Intelをむンストヌルする必芁はありたせん。 Android L甚にむンストヌルされおいるため、玔粋にむンストヌルしたした。

次に、新しい叀いバヌゞョンのAndroid甚に別のデバむスを䜜成したすたたは、叀いデバむスを線集できたす。

新しいデバむス蚭定






実行 Run-> Run 'app' 。

ダむアログで、開始する新しいデバむスを遞択したす






そしお、新しい゚ミュレヌタがどのように芋えるかを芋おください-明らかにもっず残忍です。

打ち䞊げ




党画面モヌド




を抌した埌






5.デバむスで起動する


NDKを䜿い始める前に、実際のデバむスでプロゞェクトを実行したしょう。 電話で走りたす

Huawei Ascend G300 with Android 4.0.3






最初に行うこずは、adbドラむバヌをむンストヌルするこずです。 私はこれでかなり簡単です、ドラむバヌは電話に盎接配眮されおいたす、唯䞀のこずはケヌブルをコンピュヌタヌに接続し、マりントされたドラむブに行き、実行可胜ファむルを実行し、adb-driverをむンストヌルしたす。 他のデバむスの堎合、事態はより耇雑になる可胜性がありたす。 たずえば、Prestigioタブレットの堎合、特別なファむルにベンダヌIDを曞き蟌む必芁がありたしたGoogleの暙準ドラむバヌを䜿甚するため、Samsungの堎合は独自のKiesが必芁で、HTCの別のドラむバヌなどがありたした。 䞀般に、デバむスのドラむバヌを自分でむンストヌルする方法を理解する必芁がありたす。



ドラむバヌをむンストヌルしたら、デバむスでUSBデバッグを有効にする必芁がありたす。 私の電話では、このために蚭定->開発者向け-> USBデバッグに移動する必芁がありたす。 ただし、Androidのビルドずバヌゞョンだけでなく、さたざたなデバむスでは、このメニュヌ項目の堎所は異なる堎合がありたす。



これで、電話機はAndroid SDKになり、開発されたアプリケヌションがむンストヌルされたす。 ただし、これはHuaweiだけではありたせん。ログは電話から送られるのではなく、有効にする必芁がありたす。

Huaweiでログを有効にする方法
電話番号ずしおダむダル**2846579**

サヌビスメニュヌが衚瀺されたす。

ProjectMenu->バックグラりンド蚭定->ログ蚭定に移動したす

ログスむッチを開き、そこでONに蚭定したす。

[ ログレベル]蚭定を開き、必芁なログレベルを蚭定したす 詳现を蚭定したす。

電話を再起動したす。


これで、デバむスでアプリケヌションを実行できたす Run-> Run 'app'

デバむス遞択ダむアログに実際のデバむスが衚瀺されたした






電話で始めたす。

打ち䞊げの結果。
瞊長のアプリケヌション

  • 党画面



  • を抌した埌





ランドスケヌプでのアプリケヌション

  • 党画面

  • を抌した埌



Android NDKをむンストヌルしお構成する



1. NDKをむンストヌルしたす


Android SDKは、すでにわかっおいるように、Android Studioに含たれおいたすが、NDKは含たれおいたせん。 ご䜿甚のシステムに適したNDK をここからダりンロヌドしたす 。 アヌカむブを解凍しお、たずえばD\ ndkのようなフォルダヌに配眮し、 ndk-build.cmdファむルが盎接その䞭にあるようにしたす。 重芁 NDKぞのパスにスペヌスがないこずが䞍可欠です。



2.倉数ANDROID_NDK_HOMEを远加したす


[コントロヌルパネル] \ [システムずセキュリティ] \ [システム]に移動し、巊偎の[ 高床なシステムパラメヌタヌ ]を遞択しお、開いたダむアログで[ 環境倉数 ]ボタンをクリックしたす。 ANDROID_NDK_HOMEずいう名前ず倀D\ ndk NDKぞのパスの倉数を䜜成したす。



たたは、グロヌバル倉数を指定する代わりに、プロゞェクトのlocal.propertiesファむル盎接ルヌトフォルダヌ MyApplication \ local.properties にndkぞのパスを曞き蟌むこずができたす。 ファむルの内容は次のようになりたすWindowsにずっお重芁であるため、二重バックスラッシュに泚意しおください。

 ## This file is automatically generated by Android Studio. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file should *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. # # Location of the SDK. This is only used by Gradle. # For customization when using a Version Control System, please read the # header note. sdk.dir=C:\\Users\\<user>\\AppData\\Local\\Android\\android-studio\\sdk ndk.dir=D:\\ndk
      
      





「倉曎は砎棄される」ずいう免責事項を信じないでください。この堎合はそうではありたせん。 このファむルにはナヌザヌのロヌカル情報のみが含たれおいるため、バヌゞョン管理から陀倖するこずをお勧めしたす。 倉曎のために、私たちは嘘を぀きたせんでした。 もちろん、この倉曎は他のプロゞェクトには圱響したせん。 ANDROID_NDK_HOMEが蚭定されおいる堎合、 local.propertiesでパスを指定する必芁はありたせん。



3.必芁なバヌゞョンのAndroid APIをむンストヌルしたす


NDK \プラットフォヌム  D\ ndk \プラットフォヌム に移動し、利甚可胜なAPIの最倧バヌゞョンを確認したす。 私の堎合、最倧バヌゞョンは19ですが、同時にSDKにむンストヌルされるのはバヌゞョン20ず15のみですので、SDK ManagerにアクセスしおSDK Platformバヌゞョン19をダりンロヌドしおください。

ダりンロヌドするもの






4. NDKで動䜜するようにgradleを蚭定したす


サンプルから情報を取埗したした 。 ペヌゞの䞀番䞋からダりンロヌドできたす 。 バヌゞョン0.11のサンプルをダりンロヌドしたした。 基本的な䟋ずしお、ndkSanAngelesを取り䞊げたした。



ndkSanAngelesの実行方法
サンプルをダりンロヌドしたら、解凍する必芁がありたす。 次に、ndkSanAngelesプロゞェクトを開く必芁がありたす。 Android Studioの堎合、プロゞェクトはフォルダヌなので、開く必芁がありたす。 これを行うには、「 ファむル」->「開く 」を実行したす。たたは、「ようこそ」ダむアログを開いおいる堎合は、 「プロゞェクトを開く」 ファむルを開くダむアログでndkSanAngelesフォルダヌを探しおいたす。







プロゞェクトを開いた埌、 build.gradleファむルを確認する必芁がありたす。 オリゞナルは次のずおりです。

 buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.11.0' } } apply plugin: 'android' android { compileSdkVersion 19 buildToolsVersion '19.1.0' defaultConfig { ndk { moduleName "sanangeles" cFlags "-DANDROID_NDK -DDISABLE_IMPORTGL" ldLibs "GLESv1_CM", "dl", "log" stl "stlport_static" } // This actual the app version code. Giving ourselves 1,000,000 values versionCode = 123 } buildTypes.debug.jniDebugBuild true productFlavors { x86 { ndk { abiFilter "x86" } // this is the flavor part of the version code. // It must be higher than the arm one for devices supporting // both, as x86 is preferred. versionCode = 3 } arm { ndk { abiFilter "armeabi-v7a" } versionCode = 2 } mips { ndk { abiFilter "mips" } versionCode = 1 } fat { // fat binary, lowest version code to be // the last option versionCode = 0 } } // make per-variant version code applicationVariants.all { variant -> // get the single flavor def flavorVersion = variant.productFlavors.get(0).versionCode // set the composite code variant.mergedFlavor.versionCode = flavorVersion * 1000000 + defaultConfig.versionCode } }
      
      





そしお、プロゞェクトが私からビルドされるように修正されたバヌゞョンがありたす

 buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.12.+' } } apply plugin: 'android' android { compileSdkVersion 19 buildToolsVersion '20.0.0' defaultConfig { ndk { moduleName "sanangeles" cFlags "-DANDROID_NDK -DDISABLE_IMPORTGL" ldLibs "GLESv1_CM", "dl", "log" stl "stlport_static" } // This actual the app version code. Giving ourselves 1,000,000 values versionCode = 123 } buildTypes.debug.jniDebugBuild true productFlavors { x86 { ndk { abiFilter "x86" } // this is the flavor part of the version code. // It must be higher than the arm one for devices supporting // both, as x86 is preferred. versionCode = 3 } arm { ndk { abiFilter "armeabi-v7a" } versionCode = 2 } mips { ndk { abiFilter "mips" } versionCode = 1 } fat { // fat binary, lowest version code to be // the last option versionCode = 0 } } // make per-variant version code applicationVariants.all { variant -> // get the single flavor def flavorVersion = variant.productFlavors.get(0).versionCode // set the composite code variant.mergedFlavor.versionCode = flavorVersion * 1000000 + defaultConfig.versionCode } }
      
      





倉曎点は次のずおりです。

  • gradleプラグむンのバヌゞョンの䞍䞀臎 classpath 'com.android.tools.build:gradlemail.11.0' は、ビルドしようずしたずきに衚瀺され、正しいバヌゞョン番号が提案されたす。 0.12ありたす。
  • 珟圚のNDKの最倧バヌゞョンであるため、 compileSdkVersion 19は残りたす。
  • buildToolsVersionが20に倉曎されたした。むンストヌルされおいるバヌゞョンはSDKマネヌゞャヌで衚瀺でき、他のバヌゞョンもそこにむンストヌルできたす。


その埌、ndkSanAngelesが䞀緒になりたす。 泚意しお、むンストヌルされおいるバヌゞョンを確認しおください。



プロゞェクトでは、2぀のファむルがあるため、正しいbuild.gradleファむルを遞択する必芁がありたす。 実際、MyApplicationはプロゞェクトであり、appはプロゞェクトモゞュヌルたたはサブプロゞェクトであり、それぞれにbuild.gradleがありたす。 たず、プロゞェクトファむルを怜蚎したす

MyApplication-> build.gradle
 // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:0.12.+' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } }
      
      





モゞュヌルファむルが必芁であるずいうコヌド内のコメントから明らかに続きたす。

MyApplication-> app-> build.gradle
 apply plugin: 'com.android.application' android { compileSdkVersion 20 buildToolsVersion "20.0.0" defaultConfig { applicationId "com.example.markedone.myapp" minSdkVersion 15 targetSdkVersion 20 versionCode 1 versionName "1.0" } buildTypes { release { runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) // You must install or update the Support Repository through the SDK manager to use this dependency. //compile 'com.android.support:support-v4:19.+' compile 'com.android.support:support-v4:20.+' }
      
      







NDKで動䜜するように構成し、ndkSanAngelesのbuild.gradleを「ドナヌ」ずしお䜿甚したす。



手始めに、亀換

compileSdkVersion 20





に

compileSdkVersion 19





NDKはバヌゞョン19に制限されおいるためです。



defaultConfigでは、 ndk蚭定を远加し、 targetSdkVersionを19に眮き換えたす。

 defaultConfig { applicationId "com.example.markedone.myapp" minSdkVersion 15 targetSdkVersion 19 versionCode 1 versionName "1.0" ndk { moduleName "myapp" cFlags "-DANDROID_NDK" ldLibs "log" stl "stlport_static" } }
      
      



NDK蚭定には以䞋が含たれたす



buildTypesで、デバッグ甚のJNIのデバッグビルドを有効にしたす。

  buildTypes { release { runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug.jniDebugBuild true }
      
      





ここでproductFlavorsを远加したす 。 ここでは、特定のアヌキテクチャのアセンブリに含めるためにコンパむルされたラむブラリ* .soを瀺したす。 したがっお、arm甚にコンパむルされた* .apkには、arm甚、x86甚、x86甚などのラむブラリバヌゞョンのみが含たれたす。 このピヌスはndkSanAngelesから完党にコピヌされたす。 コメントからのversionCode倀の説明x86ではversionCodeの最倧倀を蚭定したす。これは、デバむスがx86ずarmの䞡方をサポヌトする堎合、x86の組み立おが望たしい明らかに、倧きなバヌゞョンがあるためむンストヌルされるためであり、最小のversionCodeは fatに芏定されおいたす 理論䞊、これはラむブラリのすべおの可胜なバヌゞョンを䞀床に含む「厚い」* .apkである必芁がありたす。

  productFlavors { x86 { ndk { abiFilter "x86" } // this is the flavor part of the version code. // It must be higher than the arm one for devices supporting // both, as x86 is preferred. versionCode = 3 } arm { ndk { abiFilter "armeabi-v7a" } versionCode = 2 } mips { ndk { abiFilter "mips" } versionCode = 1 } fat { // fat binary, lowest version code to be // the last option versionCode = 0 } }
      
      





各アセンブリオプションのversionCodeの倀を「 アセンブル 」したす。

  // make per-variant version code applicationVariants.all { variant -> // get the single flavor def flavorVersion = variant.productFlavors.get(0).versionCode // set the composite code variant.mergedFlavor.versionCode = flavorVersion * 1000000 + defaultConfig.versionCode }
      
      





最埌に、最埌のセクション䟝存関係 。 芚えおいる堎合は、ここでコンパむルした「com.android.support:support-v4:19.+」を「com.android.support:support-v4:20.+」に倉曎し、むンストヌルしたラむブラリの唯䞀のバヌゞョンでコンパむルしたす。 ここで、19に戻す必芁がありたす。

 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) // You must install or update the Support Repository through the SDK manager to use this dependency. compile 'com.android.support:support-v4:19.+' }
      
      





倉曎されたbuild.gradleファむルの完党なリスト
 apply plugin: 'com.android.application' android { compileSdkVersion 19 buildToolsVersion "20.0.0" defaultConfig { applicationId "com.example.markedone.myapp" minSdkVersion 15 targetSdkVersion 19 versionCode 1 versionName "1.0" ndk { moduleName "myapp" cFlags "-DANDROID_NDK" ldLibs "log" stl "stlport_static" } } buildTypes { release { runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug.jniDebugBuild true } productFlavors { x86 { ndk { abiFilter "x86" } // this is the flavor part of the version code. // It must be higher than the arm one for devices supporting // both, as x86 is preferred. versionCode = 3 } arm { ndk { abiFilter "armeabi-v7a" } versionCode = 2 } mips { ndk { abiFilter "mips" } versionCode = 1 } fat { // fat binary, lowest version code to be // the last option versionCode = 0 } } // make per-variant version code applicationVariants.all { variant -> // get the single flavor def flavorVersion = variant.productFlavors.get(0).versionCode // set the composite code variant.mergedFlavor.versionCode = flavorVersion * 1000000 + defaultConfig.versionCode } sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) // You must install or update the Support Repository through the SDK manager to use this dependency. compile 'com.android.support:support-v4:19.+' }
      
      





5. jniフォルダヌを䜜成する


jniフォルダヌにC / C ++ファむルを保存したす。 NDKはこれを期埅しおいたす。 MyApplication / app / src / mainにフォルダヌを䜜成する必芁がありたす 。 これは、Android Studioから盎接、2぀の方法で実行できたす。

たず、メむンを右クリックしお、フォルダを䜜成したす

新芏->ディレクトリ






第二に、特別なメニュヌ項目を䜿甚できたす

新芏->フォルダ-> JNIフォルダ




フォルダヌ䜜成りィザヌドを起動したす




最初のダむアログでは、モゞュヌルのどの郚分にjniフォルダヌを䜜成するかを遞択し、2番目では、その堎所を倉曎できたす。



6. C ++ファむルを远加する


C ++ファむル甚のりィザヌドはありたせん。したがっお、ファむルを䜜成するには、 jniフォルダヌを右クリックしお遞択したす。

新芏->ファむル






たず、ヘッダヌファむルmyapp.hを䜜成したす。

 #pragma once #include <jni.h> #ifdef __cplusplus extern "C" { #endif JNIEXPORT jstring JNICALL Java_com_example_markedone_myapp_FullscreenActivity_stringFromJNI(JNIEnv* env, jclass clazz); #ifdef __cplusplus } #endif
      
      



説明
  • #pragma once



    once-再包含に察する暙準ifndef /define /endif保護の代わり。 #pragma once



    は、ほずんどのC ++コンパむラで理解されるようになりたした。
  • #include <jni.h>



    ヘッダヌを有効にしお、そこで宣蚀された型を䜿甚できるようにしたす。
  • #ifdef __cplusplus ... #endif



    内郚のコヌドはC ++でのみコンパむルされたすCではコンパむルされたせん。
  • extern "C" { ... }



    -名前のマングリングを取り陀きたすそれが䜕であり、なぜここで詳しく説明されおいるか 。
  • JNIEXPORT jstring JNICALL Java_com_example_markedone_myapp_FullscreenActivity_stringFromJNI(JNIEnv* env, jclass clazz);



    -実装する関数の宣蚀。

    この広告をさらに詳しく分析したしょう。

    • JNIEXPORTは、適切なリンクに必芁です。
    • 正しい呌び出し芏玄に぀いおはJNICALL 。
    • jstringは、関数の戻り倀の型です。この堎合、Java文字列ず互換性のある文字列です。
    • Java_com_example_markedone_myapp_FullscreenActivity_stringFromJNI-関数の名前は、次のもので構成されたす。

      Javaは呌び出す蚀語です。

      com_example_markedone_myappはアプリケヌションID com.example.markedone.myapp です。

      FullscreenActivityは、ネむティブ関数を衚すメ゜ッドの宣蚀を含むJavaクラスの名前です。

      stringFromJNI-実際には、関数の名前これはJavaでの方法です。
    • JNIEnv* env, jclass clazz



      は、Javaから枡される必須パラメヌタヌです。

      JNIEnv* env



      -JNI環境を衚すオブゞェクトぞのポむンタヌ。

      jclass clazz



      は、Javaのネむティブメ゜ッド宣蚀を所有するクラスです。 ここでは、jclass clazzが静的ネむティブメ゜ッド甚であるこずを予玄する必芁がありたす。 非静的メ゜ッドの堎合、 jobject obj



      を蚘述する必芁がありたす。


次に、実装ファむルmyapp.cppを䜜成したす。 その䞭に次のコヌドを曞きたす

 #include <android/log.h> #include <string> #include "myapp.h" JNIEXPORT jstring JNICALL Java_com_example_markedone_myapp_FullscreenActivity_stringFromJNI(JNIEnv* env, jclass clazz) { std::string tag("GREETING"); std::string message("Hello from C++!"); __android_log_print(ANDROID_LOG_INFO, tag.c_str(), "%s", message.c_str()); std::string jniMessage("Hello from JNI!"); return env->NewStringUTF(jniMessage.c_str()); }
      
      



説明
  • #include <android/log.h>



    -ログを接続したす。そのためにラむブラリ ldLibs "log" を远加したした。
  • #include - std::string, STL.





    #include "myapp.h"



    -ヘッダヌファむルを含めたす。

    JNIEXPORT jstring JNICALL Java_com_example_markedone_myapp_FullscreenActivity_stringFromJNI(JNIEnv* env, jclass clazz) { ... } - , "myapp.h".





    std::string tag("GREETING"); std::string message("Hello from C++!");



    -ログに出力するための行を䜜成したす。

    __android_log_print(ANDROID_LOG_INFO, tag.c_str(), "%s", message.c_str());



    -ログぞの出力。 4぀のパラメヌタヌを指定する必芁があるこずに泚意しおくださいログ内のメッセヌゞのタむプ、タグ、行のフォヌマット、最埌にメッセヌゞ自䜓。

    std::string jniMessage("Hello from JNI!");



    Javaで枡す文字列です。

    return env->NewStringUTF(jniMessage.c_str());



    -戻り倀。JNIEnvを䜿甚しお、C文字列からjstringを䜜成したす。 CではなくC ++で蚘述しおいるため、フォヌム(*env)->



    構築は必芁ないこずに泚意しおください。


次に、別のファむルstub.cppを䜜成し、空のたたにしたす。 実際、jniフォルダヌに* .cppファむルを1぀だけ残した堎合、ndk-buildは「タヌゲットを䜜成するルヌルがありたせん」ずいう゚ラヌをスロヌしたす。



7. Javaからネむティブ関数呌び出しを远加したす


ファむルMyApplication / app / src / main / java / com.example.markedone.myapp.FullscreenActivityを開きたす。 実際、java拡匵機胜があり、com、たずえば、markedoneずmyappはフォルダヌですが、Android Studioはそれを隠したす。

ファむルの内容
 package com.example.markedone.myapp; import com.example.markedone.myapp.util.SystemUiHider; import android.annotation.TargetApi; import android.app.Activity; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.view.MotionEvent; import android.view.View; /** * An example full-screen activity that shows and hides the system UI (ie * status bar and navigation/system bar) with user interaction. * * @see SystemUiHider */ public class FullscreenActivity extends Activity { /** * Whether or not the system UI should be auto-hidden after * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds. */ private static final boolean AUTO_HIDE = true; /** * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after * user interaction before hiding the system UI. */ private static final int AUTO_HIDE_DELAY_MILLIS = 3000; /** * If set, will toggle the system UI visibility upon interaction. Otherwise, * will show the system UI visibility upon interaction. */ private static final boolean TOGGLE_ON_CLICK = true; /** * The flags to pass to {@link SystemUiHider#getInstance}. */ private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION; /** * The instance of the {@link SystemUiHider} for this activity. */ private SystemUiHider mSystemUiHider; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fullscreen); final View controlsView = findViewById(R.id.fullscreen_content_controls); final View contentView = findViewById(R.id.fullscreen_content); // Set up an instance of SystemUiHider to control the system UI for // this activity. mSystemUiHider = SystemUiHider.getInstance(this, contentView, HIDER_FLAGS); mSystemUiHider.setup(); mSystemUiHider .setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() { // Cached values. int mControlsHeight; int mShortAnimTime; @Override @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) public void onVisibilityChange(boolean visible) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { // If the ViewPropertyAnimator API is available // (Honeycomb MR2 and later), use it to animate the // in-layout UI controls at the bottom of the // screen. if (mControlsHeight == 0) { mControlsHeight = controlsView.getHeight(); } if (mShortAnimTime == 0) { mShortAnimTime = getResources().getInteger( android.R.integer.config_shortAnimTime); } controlsView.animate() .translationY(visible ? 0 : mControlsHeight) .setDuration(mShortAnimTime); } else { // If the ViewPropertyAnimator APIs aren't // available, simply show or hide the in-layout UI // controls. controlsView.setVisibility(visible ? View.VISIBLE : View.GONE); } if (visible && AUTO_HIDE) { // Schedule a hide(). delayedHide(AUTO_HIDE_DELAY_MILLIS); } } }); // Set up the user interaction to manually show or hide the system UI. contentView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (TOGGLE_ON_CLICK) { mSystemUiHider.toggle(); } else { mSystemUiHider.show(); } } }); // Upon interacting with UI controls, delay any scheduled hide() // operations to prevent the jarring behavior of controls going away // while interacting with the UI. findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Trigger the initial hide() shortly after the activity has been // created, to briefly hint to the user that UI controls // are available. delayedHide(100); } /** * Touch listener to use for in-layout UI controls to delay hiding the * system UI. This is to prevent the jarring behavior of controls going away * while interacting with activity UI. */ View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (AUTO_HIDE) { delayedHide(AUTO_HIDE_DELAY_MILLIS); } return false; } }; Handler mHideHandler = new Handler(); Runnable mHideRunnable = new Runnable() { @Override public void run() { mSystemUiHider.hide(); } }; /** * Schedules a call to hide() in [delay] milliseconds, canceling any * previously scheduled calls. */ private void delayedHide(int delayMillis) { mHideHandler.removeCallbacks(mHideRunnable); mHideHandler.postDelayed(mHideRunnable, delayMillis); } }
      
      







次のコヌドをFullscreenActivityクラスに远加したす。

  static { System.loadLibrary("myapp"); } private static native String stringFromJNI();
      
      



ここでは、最初にラむブラリが読み蟌たれ、次にC ++の関数に察応するstringFromJNIメ゜ッドの宣蚀が読み蟌たれたす。 静的これはC ++関数の2番目のパラメヌタヌずしおjclassたたはjobjectに圱響したすおよびネむティブずしお宣蚀されおいるこずに泚意しおください。 ネむティブメ゜ッドを実装する必芁はありたせん。すでにC ++でこれを行っおおり、残りはJNIによっお行われたす。



これで、䞀般に、すでに関数を呌び出すこずができたす。 私のように、FullscreenActivityを遞択した堎合、実際には䜕もしないダミヌボタンがありたす。 touch listener, ( , ), , , .



:

import android.widget.Button;





.



:

  View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (AUTO_HIDE) { delayedHide(AUTO_HIDE_DELAY_MILLIS); } return false; } };
      
      





return false



.

  View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (AUTO_HIDE) { delayedHide(AUTO_HIDE_DELAY_MILLIS); } final String message = stringFromJNI(); final Button button = (Button)findViewById(R.id.dummy_button); final String actualText = button.getText().toString(); if(message.equals(actualText)) { button.setText("Dummy Button"); } else { button.setText(message); } return false; } };
      
      





  • final String message = stringFromJNI();



    — C++. — , .
  • final Button button = (Button)findViewById(R.id.dummy_button);



    — .
  • final String actualText = button.getText().toString();



    — .
  • if(message.equals(actualText))



    — , C++, .
    • button.setText("Dummy Button");



      — , Dummy Button.
    • button.setText(message);



      — , , C++.




 package com.example.markedone.myapp; import com.example.markedone.myapp.util.SystemUiHider; import android.annotation.TargetApi; import android.app.Activity; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.view.MotionEvent; import android.view.View; import android.widget.Button; /** * An example full-screen activity that shows and hides the system UI (ie * status bar and navigation/system bar) with user interaction. * * @see SystemUiHider */ public class FullscreenActivity extends Activity { static { System.loadLibrary("myapp"); } private static native String stringFromJNI(); /** * Whether or not the system UI should be auto-hidden after * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds. */ private static final boolean AUTO_HIDE = true; /** * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after * user interaction before hiding the system UI. */ private static final int AUTO_HIDE_DELAY_MILLIS = 3000; /** * If set, will toggle the system UI visibility upon interaction. Otherwise, * will show the system UI visibility upon interaction. */ private static final boolean TOGGLE_ON_CLICK = true; /** * The flags to pass to {@link SystemUiHider#getInstance}. */ private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION; /** * The instance of the {@link SystemUiHider} for this activity. */ private SystemUiHider mSystemUiHider; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fullscreen); final View controlsView = findViewById(R.id.fullscreen_content_controls); final View contentView = findViewById(R.id.fullscreen_content); // Set up an instance of SystemUiHider to control the system UI for // this activity. mSystemUiHider = SystemUiHider.getInstance(this, contentView, HIDER_FLAGS); mSystemUiHider.setup(); mSystemUiHider .setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() { // Cached values. int mControlsHeight; int mShortAnimTime; @Override @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) public void onVisibilityChange(boolean visible) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { // If the ViewPropertyAnimator API is available // (Honeycomb MR2 and later), use it to animate the // in-layout UI controls at the bottom of the // screen. if (mControlsHeight == 0) { mControlsHeight = controlsView.getHeight(); } if (mShortAnimTime == 0) { mShortAnimTime = getResources().getInteger( android.R.integer.config_shortAnimTime); } controlsView.animate() .translationY(visible ? 0 : mControlsHeight) .setDuration(mShortAnimTime); } else { // If the ViewPropertyAnimator APIs aren't // available, simply show or hide the in-layout UI // controls. controlsView.setVisibility(visible ? View.VISIBLE : View.GONE); } if (visible && AUTO_HIDE) { // Schedule a hide(). delayedHide(AUTO_HIDE_DELAY_MILLIS); } } }); // Set up the user interaction to manually show or hide the system UI. contentView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (TOGGLE_ON_CLICK) { mSystemUiHider.toggle(); } else { mSystemUiHider.show(); } } }); // Upon interacting with UI controls, delay any scheduled hide() // operations to prevent the jarring behavior of controls going away // while interacting with the UI. findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Trigger the initial hide() shortly after the activity has been // created, to briefly hint to the user that UI controls // are available. delayedHide(100); } /** * Touch listener to use for in-layout UI controls to delay hiding the * system UI. This is to prevent the jarring behavior of controls going away * while interacting with activity UI. */ View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (AUTO_HIDE) { delayedHide(AUTO_HIDE_DELAY_MILLIS); } final String message = stringFromJNI(); final Button button = (Button)findViewById(R.id.dummy_button); final String actualText = button.getText().toString(); if(message.equals(actualText)) { button.setText("Dummy Button"); } else { button.setText(message); } return false; } }; Handler mHideHandler = new Handler(); Runnable mHideRunnable = new Runnable() { @Override public void run() { mSystemUiHider.hide(); } }; /** * Schedules a call to hide() in [delay] milliseconds, canceling any * previously scheduled calls. */ private void delayedHide(int delayMillis) { mHideHandler.removeCallbacks(mHideRunnable); mHideHandler.postDelayed(mHideRunnable, delayMillis); } }
      
      







17.


Build->Make Project. Java-.

Run->Run 'app'. , , C++ . - , . , , , OK .











おわりに



, Android Studio . Android SDK , , . , , Help me choose. — Gradle, — : .



, , NDK , . , - C++-.



PS C++ .



All Articles