2014年3月18日火曜日

「ガヤざわニュースランキング」iOS版を本日リリースいたしました

ようやくappleからの承認がおり、

ヤフーニュース様のニュースの中で、ユーザーからの
コメント数が多いニュースをランキング別に紹介するアプリ

「ガヤざわニュースランキング」



を本日appstoreにて公開開始しました。
様々なニュースジャンルにて上位20件の表示が可能です。

尚、Android版からの追加機能が1点あります。
「過去のランキングを100件まで保存できる」という点です。

ニュース好きの方々にご活用頂ければと思っております。

宜しくお願い致します。

2014年3月15日土曜日

意外に日本語の解説が少ないandroidのcrash dump の調べ方

androidのndkだかにndk-stackのファイルがありますんで、
このファイルがあるディレクトリまで移動して以下のようなコマンドぶちこんでください

adb logcat | ./ndk-stack -sym /プロジェクトのフルパス/proj.android/obj/local/armeabi

そもそもadbコマンドって何よ?みたいな方は以下参照

http://www.javadrive.jp/android/commnadline/index5.html

以下のようにしていつでもadbが使えるようにした方が吉です

ターミナルを起動します。
アプリケーションー>ユティリティー>ターミナル
エディタを起動しましょう。
有名なviなどのエディタがありますが、今回はパスを通すだけですし初心者(自分)でも簡単に使えるのでpicoを使います。

ホームディレクトリに移動
cd ~

Picoで.bash_profileを開きます(もし、ない場合は自動的に作成されます。)
pico .bash_profile

.bash_profileにAndroid SDKのパスを通します。
export PATH=$PATH:AndoroidSDKのあるディレクトリ/platform-tools


ここで初めて.bash_profile作った方、cd や lsなどが使えなくなった!?どうしよう!?
と思う方もいると思いますので、私の記載例を書いておきます。

export PATH="$PATH:/bin:/usr/bin:/usr/local/bin"

export PATH=$PATH:/adt-bundle-mac-x86_64/sdk/platform-tools

1行目も書いておけば全く問題ないですよ。


androidでgreeさんのccwebviewを利用する時の注意事項

2月に更新した際も触れましたccwebviewプラグインを導入する際の注意事項です。
以前のブログはこちら

cocos2dxへのパッチの手動での当て方がもう全然わからなかったんですが、
以下のスライドを見てほぼ理解しました。
http://www.slideshare.net/doraemonsss/20130314-cocos2d-x

本も読ませて頂きましたが、清水さん本当に有難うございます。

どうやら以下ファイルを修正する必要があるようです。
全てcocos2dxを読み込めばわかることですが、正直きついっすよね。
よっぽどギークでない限り。。。

このファイルをいじります。

cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxHelper.java



そしてこんな感じで、webviewプラグインのパッチを当てます。

 import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.WindowManager;
+import org.cocos2dx.lib.gree.webview.Cocos2dxWebView;
 
 public class Cocos2dxHelper {
  // ===========================================================
   Cocos2dxHelper.sAssetManager = pContext.getAssets();
   Cocos2dxBitmap.setContext(pContext);
   Cocos2dxETCLoader.setContext(pContext);
+  
+  //和泉webview追加
+  Cocos2dxWebView.setContext(pContext);
  }
 
  // ===========================================================


このあて方、初心者にはわからないですよね。。。
今後の後学になると思ったのでメモしました。

cocos2dxでlibiconvを利用する方法(iOS,Android版)

さて、ほんとうにこのブログにたまたま足を踏み入れた方が
気になっているかもしれない上記をお話します。

まずはiOS版から
これは簡単です。

general からframewarkで+を選択、検索ワード「libiconv」と検索すると該当のファイルがでるので、追加すればOK!

class上ではincludeして読み込みします
+//これはiconvを利用するためのヘッダ(htmlをiOSで読み取るutf8に変換するため)
+#include <iconv.h>//ちゃんとiOS側のgeneralにも追加して

そして該当ソースとしてはこんな感じ

filepathとfilepath2がありますが、これはコンバート前、後のファイルの場所を指定しています。

+    iconv_t icd;
+    FILE *fp_src, *fp_dst;
+    char s_src[S_SIZE], s_dst[S_SIZE];
+    char *p_src, *p_dst;
+    size_t n_src, n_dst;
+    
+    icd = iconv_open("UTF-8", "EUC-JP");
+    fp_src = fopen(filePath.c_str(), "r");
+    fp_dst = fopen(filePath2.c_str(), "w");
+    
+    while(true){
+        fgets(s_src, S_SIZE, fp_src);
+        if (feof(fp_src))
+            break;
+        p_src = s_src;
+        p_dst = s_dst;
+        n_src = strlen(s_src);
+        n_dst = S_SIZE-1;
+        while(0 < n_src){
+            iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
+        }
+        *p_dst = '\0';
+        fputs(s_dst, fp_dst);
+    }
+    
+    fclose(fp_dst);
+    fclose(fp_src);
+    iconv_close(icd);

これで問題なく、ファイルのコンバートができました。

そして次はAndroid版です。
これがなかなか初心者にとってはつらかった点くせ者でした。

まずはlibiconv-1.14をDLしてきます。

そして私は以下ディレクトリを作成してぶちこみました

external/libiconv2


そしてプロジェクトのモジュールとして利用したいので、
以下のAndroid.mkファイルを作成
external/libiconv2/Android.mk
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#libiconv.so
+LOCAL_MODULE := iconv_static
+
+LOCAL_MODULE_FILENAME := libiconv
+
+LOCAL_CFLAGS := \
+  -Wno-multichar \
+  -DANDROID \
+  -DLIBDIR="c" \
+  -DBUILDING_LIBICONV \
+  -DIN_LIBRARY
+
+LOCAL_SRC_FILES := \
+  libiconv-1.14/libcharset/lib/localcharset.c \
+  libiconv-1.14/lib/iconv.c \
+  libiconv-1.14/lib/relocatable.c
+
+LOCAL_C_INCLUDES += \
+  $(LOCAL_PATH)/libiconv-1.14/include \
+  $(LOCAL_PATH)/libiconv-1.14/libcharset \
+  $(LOCAL_PATH)/libiconv-1.14/lib \
+  $(LOCAL_PATH)/libiconv-1.14/libcharset/include \
+  $(LOCAL_PATH)/libiconv-1.14/srclib
+ 
+LOCAL_EXPORT_C_INCLUDES       := $(LOCAL_PATH)/libiconv-1.14/include
+include $(BUILD_STATIC_LIBRARY)

そして該当プロジェクトのAndroid.mkファイルも修正しないといけません。
上記のlibiconvを読み込む必要があるためです

proj.android/jni/Android.mk
 LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
 LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static
 LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static
+LOCAL_WHOLE_STATIC_LIBRARIES += iconv_static 
 
 include $(BUILD_SHARED_LIBRARY)
 
 $(call import-module,cocos2dx)
 $(call import-module,CocosDenshion/android)
 $(call import-module,extensions)
 $(call import-module,external/Box2D)
 $(call import-module,external/chipmunk)
+$(call import-module,external/libiconv2)

こんな感じで、

そして該当classにて以下のようにincludeさせることで利用可能となりました
+#include <../../external/libiconv2/libiconv-1.14/include/iconv.h>

実装のソースはAndroidでは以下のように少し修正してます

     iconv_t icd;
     FILE *fp_src, *fp_dst;
     char s_src[S_SIZE], s_dst[S_SIZE];
-    char const *p_src;
+    char *p_src;
     char *p_dst;
     size_t n_src, n_dst;
     
     icd = iconv_open("UTF-8", "EUC-JP");
     fp_src = fopen(filePath.c_str(), "r");
     fp_dst = fopen(filePath2.c_str(), "w");
     
     while(true){
         fgets(s_src, S_SIZE, fp_src);
         if (feof(fp_src))
             break;
         p_src = s_src;
         p_dst = s_dst;

ちょっとライブラリにより、const を使っているもの、使っていないものがあるようです

これで問題なくコンパイルは通過したのですが、さらなる問題が、、、

実は上記のclassを単独の別クラスにして、他のアプリでも流用が簡単にしようと思ったのですが、iOSだとその状態でも問題なく動作可能。

しかしAndroidではコンパイルは通過するものの、ネイティブ側で以下のエラーが発生

logcatの情報です

03-03 16:48:45.170: I/dalvikvm(1046): Wrote stack traces to '/data/anr/traces.txt'
03-03 16:48:45.211: I/DEBUG(33): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
03-03 16:48:45.211: I/DEBUG(33): Build fingerprint: 'generic/sdk/generic:4.0.4/MR1/302030:eng/test-keys'
03-03 16:48:45.211: I/DEBUG(33): pid: 1046, tid: 1046  >>> com.zawazawa.hotspring <<<
03-03 16:48:45.211: I/DEBUG(33): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
03-03 16:48:45.221: I/DEBUG(33):  r0 deadbaad  r1 00000001  r2 40000000  r3 00000000
03-03 16:48:45.221: I/DEBUG(33):  r4 00000000  r5 00000027  r6 00000001  r7 001a0c90
03-03 16:48:45.221: I/DEBUG(33):  r8 b0012fa8  r9 46e5a000  10 00562000  fp be8b026c
03-03 16:48:45.221: I/DEBUG(33):  ip ffffffff  sp be8b0228  lr 4001f161  pc 4001b8c0  cpsr 60000030
03-03 16:48:45.221: I/DEBUG(33):  d0  3f8000003f800000  d1  3ff0000043200000
03-03 16:48:45.221: I/DEBUG(33):  d2  437e8000000000fe  d3  000000003f000000
03-03 16:48:45.221: I/DEBUG(33):  d4  000001fd00000000  d5  3fe999999999999a
03-03 16:48:45.221: I/DEBUG(33):  d6  3fe8000000000000  d7  000000a000000000
03-03 16:48:45.231: I/DEBUG(33):  d8  0000000000000000  d9  0000000000000000
03-03 16:48:45.231: I/DEBUG(33):  d10 0000000000000000  d11 0000000000000000
03-03 16:48:45.231: I/DEBUG(33):  d12 0000000000000000  d13 0000000000000000
03-03 16:48:45.231: I/DEBUG(33):  d14 0000000000000000  d15 0000000000000000
03-03 16:48:45.231: I/DEBUG(33):  scr 60000012
03-03 16:48:45.641: I/Process(78): Sending signal. PID: 1046 SIG: 3
03-03 16:48:45.641: I/dalvikvm(1046): threadid=3: reacting to signal 3
03-03 16:48:45.691: I/dalvikvm(1046): Wrote stack traces to '/data/anr/traces.txt'
03-03 16:48:45.891: I/DEBUG(33):          #00  pc 000178c0  /system/lib/libc.so
03-03 16:48:45.891: I/DEBUG(33):          #01  lr 4001f161  /system/lib/libc.so
03-03 16:48:45.901: I/DEBUG(33): code around pc:
03-03 16:48:45.901: I/DEBUG(33): 4001b8a0 4623b15c 2c006824 e026d1fb b12368db  \.#F$h.,..&..h#.
03-03 16:48:45.901: I/DEBUG(33): 4001b8b0 21014a17 6011447a 48124798 24002527  .J.!zD.`.G.H'%.$
03-03 16:48:45.901: I/DEBUG(33): 4001b8c0 f7f47005 2106ee50 eeecf7f5 460aa901  .p..P..!.......F
03-03 16:48:45.901: I/DEBUG(33): 4001b8d0 f04f2006 94015380 94029303 eaa8f7f5  . O..S..........
03-03 16:48:45.901: I/DEBUG(33): 4001b8e0 4622a905 f7f52002 f7f4eab2 2106ee3c  .."F. ......<..!
03-03 16:48:45.901: I/DEBUG(33): code around lr:
03-03 16:48:45.911: I/DEBUG(33): 4001f140 41f0e92d 46804c0c 447c2600 68a56824  -..A.L.F.&|D$h.h
03-03 16:48:45.911: I/DEBUG(33): 4001f150 e0076867 300cf9b5 dd022b00 47c04628  gh.....0.+..(F.G
03-03 16:48:45.911: I/DEBUG(33): 4001f160 35544306 37fff117 6824d5f4 d1ee2c00  .CT5...7..$h.,..
03-03 16:48:45.911: I/DEBUG(33): 4001f170 e8bd4630 bf0081f0 0002839a 41f0e92d  0F..........-..A
03-03 16:48:45.921: I/DEBUG(33): 4001f180 fb01b086 9004f602 461f4815 4615460c  .........H.F.F.F
03-03 16:48:45.921: I/DEBUG(33): memory map around addr deadbaad:
03-03 16:48:45.921: I/DEBUG(33): be89c000-be8b1000 [stack]
03-03 16:48:45.921: I/DEBUG(33): (no map for address)
03-03 16:48:45.921: I/DEBUG(33): (no map above)
03-03 16:48:45.921: I/DEBUG(33): stack:
03-03 16:48:45.921: I/DEBUG(33):     be8b01e8  00143b70  [heap]
03-03 16:48:45.931: I/DEBUG(33):     be8b01ec  4004c35c  
03-03 16:48:45.931: I/DEBUG(33):     be8b01f0  400476b0  /system/lib/libc.so
03-03 16:48:45.931: I/DEBUG(33):     be8b01f4  001a0c90  [heap]
03-03 16:48:45.931: I/DEBUG(33):     be8b01f8  4004770c  /system/lib/libc.so
03-03 16:48:45.931: I/DEBUG(33):     be8b01fc  4004c85c  
03-03 16:48:45.931: I/DEBUG(33):     be8b0200  00000000  
03-03 16:48:45.931: I/DEBUG(33):     be8b0204  4001f161  /system/lib/libc.so
03-03 16:48:45.942: I/DEBUG(33):     be8b0208  00000000  
03-03 16:48:45.942: I/DEBUG(33):     be8b020c  be8b023c  [stack]
03-03 16:48:45.951: I/DEBUG(33):     be8b0210  00000001  
03-03 16:48:45.951: I/DEBUG(33):     be8b0214  001a0c90  [heap]
03-03 16:48:45.951: I/DEBUG(33):     be8b0218  b0012fa8  
03-03 16:48:45.951: I/DEBUG(33):     be8b021c  4001e2cd  /system/lib/libc.so
03-03 16:48:45.951: I/DEBUG(33):     be8b0220  df0027ad  
03-03 16:48:45.951: I/DEBUG(33):     be8b0224  00000000  
03-03 16:48:45.961: I/DEBUG(33): #00 be8b0228  400476b0  /system/lib/libc.so
03-03 16:48:45.961: I/DEBUG(33):     be8b022c  0000000a  
03-03 16:48:45.961: I/DEBUG(33):     be8b0230  00000001  
03-03 16:48:45.961: I/DEBUG(33):     be8b0234  4001f6f1  /system/lib/libc.so
03-03 16:48:45.971: I/DEBUG(33):     be8b0238  40047608  /system/lib/libc.so
03-03 16:48:45.971: I/DEBUG(33):     be8b023c  fffffbdf  
03-03 16:48:45.971: I/DEBUG(33):     be8b0240  00000001  
03-03 16:48:45.981: I/DEBUG(33):     be8b0244  40047608  /system/lib/libc.so
03-03 16:48:45.981: I/DEBUG(33):     be8b0248  001eb23c  [heap]
03-03 16:48:45.981: I/DEBUG(33):     be8b024c  46cb3f18  /data/data/com.zawazawa.hotspring/lib/libcocos2dcpp.so
03-03 16:48:45.981: I/DEBUG(33):     be8b0250  0019ceb0  [heap]
03-03 16:48:45.981: I/DEBUG(33):     be8b0254  00000000  
03-03 16:48:45.981: I/DEBUG(33):     be8b0258  0019ceb0  [heap]
03-03 16:48:45.981: I/DEBUG(33):     be8b025c  46cb3e00  /data/data/com.zawazawa.hotspring/lib/libcocos2dcpp.so
03-03 16:48:45.981: I/DEBUG(33):     be8b0260  46cafaf0  /data/data/com.zawazawa.hotspring/lib/libcocos2dcpp.so
03-03 16:48:45.981: I/DEBUG(33):     be8b0264  ffffffff  
03-03 16:48:45.981: I/DEBUG(33):     be8b0268  be8b0274  [stack]
03-03 16:48:45.981: I/DEBUG(33):     be8b026c  46cafac4  /data/data/com.zawazawa.hotspring/lib/libcocos2dcpp.so

こりゃあcrash dumpを以下コマンドでみなきゃあと思ったら、
さらにlibc.soしかログにはでてない。。。

もう謎過ぎたので、ライブラリを一つ一つ消して、追加して、
動作確認しました。

そして迷ったはてに、libiconv利用してファイルの文字コードをコンバートするものを単独別クラス化していたものを、コンバートしたものを表示するクラスと同じところに、
メンバ関数の一つとして追加したら、なぜかネイティブ側でも落ちなくなりましたよ。。。そうとう謎です。

もし原因がわかる方いらっしゃいましたら、ご指摘頂けますと嬉しいです。

androidは不慣れでしたが、crashdumpして、ログにもlibc.soで落ちたことしかわからない様だったら、「一つ一つのライブラリで動作試してみて」
さらにどうしてもだめなら、「全て一緒のクラス内で書いてみる」

学んだことでした。

うーん、開発は奥が深い。。。