× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
公式ページ
Qiitaの記事 設定ファイルを作るページ このjsonをapp/以下に配置する xmlは app/src/main/res/xml/app_tracker.xml にある。ここにトラッカーIDなど記述する app/res/xml/ ではないことに注意。 PR |
|
アプリの外部ストレージにファイルを保存した時とか、
ちゃんとファイルがあるか調べたい時など。 $ adb shell $ run-as パッケージ名 でok. 一応、AndroidStudioで Tools -> Android -> Android Device Monitor というものもあるが、権限がなかったりであまり中が見えないので使いにくい |
謎現象。
iOSでは起きないが、Androidで発生
こういうラムダ式があって、 func1を実行した後、func2の中で セグメンテーションフォルトで落ちた。 いろいろ調べてみると、thisの値がなぜか書き換わっていた。 func1()の中を処理している間は良いのだが、func1()からここに戻ってきた時に全然別の値になっている。 それでfunc2()を呼び出したもんだから何が起きるかわからない。 で、以下のようにthisを別の変数にもたせておけば、落ちずに進行した
しかしなぜthisが落ちるのか。 thisは暗黙的にコピーキャプチャーされている。 コピーキャプチャーされた変数は暗黙的にconstがついているはずだ。なぜなのか。 仮説 thisはちゃんとクラスインスタンスのことを表してるのか? ラムダ式のインスタンス自身を表す変数もthisで、こちらと混同しているのか?(しかしラムダ式のthisを指定できる言語仕様なのか?そんなもの必要ない気がするし) ->解決 このラムダ式の中で、 ラムダ式自身を破棄していた。 そのため、関数を戻る時に、不定の位置に戻ってしまって(リターンコードが破棄されて別の値が書き込まれていた) セグメンテーションフォルトになっていたのだった。 iOSでバグらなかったのは、そのメモリ位置がたまたま再利用されずそのまま残っていたからだろう というわけで、ラムダ式は悪くない |
実機に転送して、実行しようとした時、以下のエラーが出る
java.lang.UnsatisfiedLinkError: dlopen failed: unknown reloc type 160 調べたところ、スタティックライブラリをc++_staticにしていることが原因らしい。 cocos2d_libとc++_staticの相性の問題のようだ。困ったものだ 参考 デフォでは、gnustl_static を指定しているのだが(cocosプロジェクトが作られた時もそうなっている)、 gnustl_staticは以下のようなメソッドが使えない(コンパイルエラーになる) std::to_string std::stol std::stoul std::stoll std::stoull std::stof std::stod これはndkの怠慢じゃないかと思うのだが、ともかく こちらを立てればあちらが立たずの状態になっている。 仕方ないので、 gnustl_staticを使用し、 std::文字列系の処理を自前で実装することにする。 実装は以下のとおり AndroidHelper.h
AndroidHelper.cpp
|
gitignore参考
|
前の記事のように記述してビルドしたところ、実機で実行時にエラーが発生
Cannot load library: reloc_library[1285]: cannot locate 'rand' 参考 原因は、API-21(Android5.0)でコンパイルしたアプリを、API-20以下の端末で実行したことらしい 謎だ |
以下の記述はセットで機能する。
import-add-path に書かれたパスから、 import-module に書かれたディレクトリ下のAndroid.mkをインポートする。 上記だと、 cocos2d/external/Box2D/Android.mk cocos2d/extensions/Android.mk などがインポートされることになる。 それぞれのAndroid.mkにもまた 読み込むソースファイルやモジュール、ライブラリが記述してあるわけだ LOCAL_WHOLE_STATIC_LIBRARIES リンカの–whole-archiveオプションのこと。 これを指定した静的ライブラリは、ライブラリ全体が実行ファイルに含まれることになる(必要な部分だけをstripするということをしなくなる) 参考 最新のcocos2d-xのデフォルトプロジェクトでは、この指定はなくなっている |
iOS版はすでに動いている
cocos2d-x バージョン3.7 AndroidStudio バージョン1.3 (作業中に1.5.1にアップデート) AndroidStudioに対応したcocos2d-xのバージョンだと、プロジェクトのディレクトリに proj.android-studio/ が作られている。 まずはAndroidStudioを開いてみる ディレクトリは前述の場所を選択。 すると以下のエラーが出た どうやらJDKの指定が悪い様子。 JDKのパスを確認する方法は を選択。 すると以下のような画面になる 下部にエラー内容が書いてある。 "Please choose a valid JDK directory." つまり、以下のパスを修正しろということだ /System/Library/Java/JavaVirtualMachine/1.6.0.jdk/Contents/Home このパスが間違っているわけではないはずなのだが(Eclipseの時はこれで動いていたので) 変えた方が良さそうだ。 ひとまずjdkの最新をダウンロードしてみる。 ダウンロードページ ダウンロードされた場所は以下。 /Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home このパスを指定すると、エラーが消えた。 ついでに、Android SDK のパスも変更。 adt-bundle-mac-x86_64-20140321 になっているが、昔のeclipseのダウンロードした時のままなのであまりふさわしくない (中にAPI level別のディレクトリが入っているし) 変更。 この場合、 ~/.bash_profile の中身の ANDROID_SDK_ROOT を書き換え、 $ source ~/.bash_profile を実行する。 また、ポップアップに従って、AndroidStudioをアップデートした。 次に、 Android.mkの指定をする必要がある。 LOCAL_SRC_FILESの部分は変更が必須。 Classesディレクトリ以下のすべての.cppと.hを正しくビルドに含めるために、以下のように記述。
また、AndroidStudioからディレクトリ階層が一つ深くなっているので、そこも変更 なおこのコマンドが実行される時のカレントディレクトリ(Android.mkのある場所)は proj.android-studio/app/jni/ である。 これでビルドしてみる。
コンパイルして実行もする場合は以下のように
ANDROID PLATFORM(android SDK バージョン)を、AndroidStudioで使用しているのと違うものを指定したい場合は、ap オプションで指定できる
が、エラーが結構出る。 特に困るのが、stringクラスが使えないこと。 error: 'to_string' is not a member of 'std' みたいな。 NDKのSTLに含まれていないらしい。なんと不便な to_stringだけなら自前実装もできるが、stolとか軒並み駄目なので、なんとかしたい。 Application.mkの先頭行を
から
に書き換えると、できるようになる。 参考ページ 指定できるライブラリ一覧 ライブラリを追加する方法は で選択。 決定すると、自動でダウンロード、ビルドされる。 また、build.gradleにも自動で書き込まれている。 しかし、これもエラーが。 No resource found the matches the given name 'android:TextAppearance.Material.Widget.Button.Inverse' 原因は、APIレベルがあっていないことらしい 以下の対応をしたら直った ・Project Structureウィザードで、プロジェクトのBuildToolVersionを23.0以上にする ・build.gradleに以下を記述 compile 'com.android.support:support-v4:23.1.1' 参考 これらを対応してようやっとビルドに成功。 しかしまだ気になるワーニングがある
Project Structureを見ると、ご丁寧にNDKのダウンロードができるようになっている。 クリックして、ダウンロードする(10分ほどかかる) すると、自動的にディレクトリがセットされる (ダウンロードディレクトリは、ANDROID_SDK_ROOT/ndk-bundle になる) このディレクトリをbash_profileのNDK_ROOTに書き、 $ source ~/.bash_profile を実行すれば、ワーニングは消えた |