JniHelper::getStaticMethoInfo


いつも間違えるので、備忘録。

void InterfaceJNI::funcSendfloat(const char* value1, float value2){

  JniMethodInfo t;
  if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "function_name", "(Ljava/lang/String;F)V")){

    jstring stringArg1 = t.env->NewStringUTF(value1);

    t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1, value2);
    t.env->DeleteLocalRef(stringArg1);
    t.env->DeleteLocalRef(t.classID);
  }
}



ま、こんな感じで指定しているのですが、文字列じゃない引数が複数あるとき、つい「;」をトークン的につけちゃう。
例えば Int 型3つだと、こんな感じ。

×   if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "function_name", "(I;I;I;)V")){
○   if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "function_name", "(III)V")){

文字列型の指定の Ljava/lang/String; の最後の「;」をトークンだと思っちゃうんだけど、大きな間違い。

「;」を含めて文字列の引数を表しているので、文字列型が複数ある場合は、

×   if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "function_name", "( Ljava/lang/String; Ljava/lang/String)V")){
○   if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "function_name", "( Ljava/lang/String; Ljava/lang/String;)V")){

最後に「;」が必要。

こちら様 が参考になりました。

エラー・メッセージ Failed to find static method id of ~ で、半日悩んで、やっと解消できたーと思ったら、実は役に立たない機能だったわけですよ。そんなのばっかり。

スポンサーサイト

cocos2d-x クリーン・ビルド?


作ったアプリが一部端末で動かない? という、互換関係の問題かも? な対処で、NDKのバージョンや、cocos のバージョンを上げ下げしてたら、アックアップしておいた正常なプロジェクトまで、コンパイルできなくなるという、勘弁してくれーな状況に。

で、クリーン・ビルドすれば良いんじゃないの? と思ったまではいいけど、さて、やり方が分からない。

エラーはこんな感じ。

make: *** No rule to make target /xxx/proj.android-studio/../cocos2d/cocos/editor-support/cocostudio/CCActionFrame.cpp', needed by obj/local/armeabi/objs-debug/cocostudio_static/CCActionFrame.o'. Stop.



検索したところ、こんなご意見 が。

proj.android-studio/app/obj フォルダ内の local フォルダを削除しちゃえよ、と。
local フォルダがないと、クリーン・ビルドするみたいよ、と。

あー、そうだったのかー。

cocos のバージョンを変えて、再構築するのってどうやるのか、良く分からなかったんすよねー。

バージョンを上げたあと、cocos new して、出来た cocos2d フォルダを、プロジェクトのフォルダにコピーしてやれば良いのかなぁとか思ってたんだけど。
そのあと、local フォルダを削除すれば良かったのかも知れない。
今は試せない。

Cocosじゃなくて、Android 問題か? Invalid attribute name:


cocos compile -p android --android-studio を実行すると、

Invalid attribute name: android:name

が表示されるようになってしまった。

いや、以前から出てて、今、気がついただけなのかも知れない。

アプリ自体は問題なく動いているような気がするんだけど、どうにもキモチワルイので、ネット検索したものの、同じ症状で悩んでいる人はいないもよう。

なんとなく、AndroidManifest ぽい気もするので、内容をチェックして、警告を出ているところをチェックしてるんだけど、これと言って・・・。

で、application タグに警告が出ていたので対処しようとしたところ・・・。

Android SDK 23 から自動バックアップ機能がついたらしく、Application タグ内でどうするか指定しろって警告が出ていたので、対応しようと android:allowBackup = "false" にしたら、エラー。
ザックリ解説を読むと、アプリのデータをクラウドに自動バックアップしておいて、もし、アプリをアンインストールしても、再インストールしたときには、データをクラウドから復帰させる・・・、みたいに思えるんだけど、そんな複雑なことしてないのよね・・・。

エラー回避で、 android:allowBackup = "true" にしておくには、データ用の xml ファイルを指定しろと言われているようなんだけど、もう1つ指定の仕方が分からない。
res に xml フォルダを作って、適当な名前で xml ファイルを作って、

android:fullBackupContent="@xml/適当な名前"

とかやってやれば良さそうな気もするんだけど、必要ないしなぁ・・・。

というわけで、放置。

そもそも、なんで android:allowBackup = "true" にしたか忘れてるあたり・・・。


App is not indexable by Google Search ~ って、なんぞ、これ? と、調べてみると 公式に こんな物 が。

うーん、SEO とかいうものにヤクニタツノカ ???

なんのこっちゃ? と思いつつ、こっち を見て、activity タグをクリックして、左側に出る電球マークをクリック、Add URL してみる。

なにやら、「必要があるなら、ホストとか、パスのプリフィックスを書き直せ」と言われているような気がするけど、この辺も良く分からないので放置。

というわけで、当初の Invalid attribute name: 問題はまるで解決しないのであった。


Cocos2d-x 3.11 の MessageBox が・・・。


Eclipse + ADT & Cocos2d-x 3.06 で作ったプロジェクトを Android Studio に移行していたのですが、ついでだからと Cocos2d-x を 3.11 に上げたら、MessageBox の表示が変わっているような???

なぜか2行までしかテキストを表示しないんですけど、これって、元からだったかなぁ?

複数行にわたってコピーライト表記してるので、マズイんですよねぇ。
JNI で Java で表示するかー。面倒だから、 MessageBox 使ったんだけどなぁ。

Cocos2d-x のダイアログ非対応は、結構、ネット検索してもヒットするんだけど、対応する方向じゃなくて、無くす方向に進んでいるのかしらねぇ。

【追記】

悩んでいてもしょうがいないので、やってみた。MessageBox を アラート・ダイアログに置き換えただけ。
.h は省略。

Main.cpp

void Main::AlertDialog(const char* title, const char* msg){
    InterfaceJNI::funcAlertDialog(title, msg);
}



InterfaceJNI.cpp

void InterfaceJNI::funcAlertDialog(const char* title, const char* msg){
    JniMethodInfo t;
    if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "funcAlertDialog", "(Ljava/lang/String;Ljava/lang/String;)V")){

        jstring stringArg1 = t.env->NewStringUTF(title);
        jstring stringArg2 = t.env->NewStringUTF(msg);

        t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1, stringArg2);
        t.env->DeleteLocalRef(stringArg1);
        t.env->DeleteLocalRef(stringArg2);
        t.env->DeleteLocalRef(t.classID);
    }



AppActivity.java

public static void funcAlertDialog(final String title, final String msg){

    Cocos2dxHelper.getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
        new AlertDialog.Builder(getContext())
            .setTitle(title)
            .setMessage(msg)
            .setPositiveButton("OK", null)
            .show();
        }
    });
}



意外に、AppActivity 側でハマった。

runOnUiThread を使わなきゃいけないところと、引数を渡すのに final を使うところ。
って、基本じゃねーか。

拡張すれば、アラート・ダイアログのボタンを押したときのコールバックなんかも作れるかも知れませんね。
やらないけど。


【追記その2】

あ、もしかしたら、MessageBox のテキスト順序が変わったのかも知れない。

以前は、
MessageBox("表示したい内容", "タイトル");

だったけど、
MessageBox("タイトル", "表示したい内容");

という、真っ当(?)な順序になったのか? そういや、タイトルが下に来てたなぁ。

確認してみたらビンゴでした。
返して! ワタシの今日1日を返して!

Android Studio で Cocos2d-x 【cocos compile 後の No Changes to Deploy問題】


cocos compile -p android --android-studio を実行したあとに、Run しても、cpp ソースの変更が反映されないという問題ですが、 その後、調べたところ、multidex に関連しているもよう。

一瞬だけ警告が出ているみたいで、見逃していた。

なので、昨日対処した方法 を試してみる。

AndroidManifest.xml

    <application

        android:name="android.support.multidex.MultiDexApplication"
    >



アプリの build.gradle

    defaultConfig {

        // Enabling multidex support.
        multiDexEnabled true
    }


dependencies {

    compile 'com.android.support:multidex:1.0.0'
}



一応、これで、cocos compile 後に、Run するだけで、cpp の変更が反映されるようになりました。
これまでは、セーブしてから、cocos compile してたんですが、それも必要なさそうです。
良かった、良かった。


話は変わるけど、Android Studio 関連の作業中、Pure Data のことを調べていたら、libpd4unity なる物をを発見した。
Github のタイムスタンプを見るとそれほど活発な動きではないみたいだけど、ちょっと試してみたい気もする。