2014年2月26日水曜日

androidのListViewでスクロールする時、最初だけカクつく(ラグる)

AndroidのListViewでスクロールする時、初回だけカクついてそれ以降はスムーズになる場合がある。例えばTwiccaのスクロールはこうなる。

このラグを無くすにはAndroidManifestのapplicateionタグに
        android:hardwareAccelerated="true"
を足す。
これだけ。お試しあれ。

2014年2月5日水曜日

Android + NDK debug で No source file named *****.c の原因

AndroidのNDKでnativeのコードをデバッグしようとすると
ブレークポイントを貼ったソースファイル名で

 No source file named *****.c

というようなエラーが出た。

原因は簡単で、先に

static {
System.loadLibrary("mylibrary");
}

のように共有ライブラリーをロードしなければいけないのでした。

2014年1月21日火曜日

Xcode5で.hファイルと.mファイルの切り替え

Xcode5 で ヘッダファイルとモジュールファイルを切り替えるショートカット
 +  + [↑|↓]
Ctrl + Cmd + [up|down]

2014年1月9日木曜日

JNIサンプル集


順次追加していきます

メソッドシグネチャ

型一覧
voidV
booleanZ
byteB
charC
shortS
intI
longJ
doubleD
floatF
StringLjava/lang/String;
ObjectLjava/lang/Object;
その他のクラス"L"+"完全修飾クラス名(スラッシュ区切り)"+";"


[をつけると配列を表す

boolean array[Z
byte array[B
char array[C
short array[S
int array[I
long array[J
double array[D
float array[F
String array[Ljava/lang/String;
Object array[Ljava/lang/Object;


メソッドシグネチャは
(引数)戻り値
の形で表す。
引数が複数ある場合は連続して記述する。
引数が無い場合は括弧の中に何も書かない。

メソッドシグネチャの実例
void hoge();"()V"
void hoge(int a);"(I)V"
int hoge(int a)"(I)I"
int hoge(int a, int b)"(II)I"
long hoge(short a, double b)"(SD)J"
boolean hoge(String a);"(Ljava/lang/String;)Z"
boolean hoge(int a[], char b, byte c[] )"([ab[c)Z"

java メンバーメソッドの呼び出し

例:その関数を呼び出したjavaオブジェクトのメンバーメソッドhogeを呼び出す関数
上がvoid hoge();
下がint hoge(int a, int b );

JNIEXPORT void JNICALL naHoge( JNIEnv* env, jobject obj){
     jclass clsj = env->GetObjectClass(obj);
     jmethodID func = env->GetMethodID(clsj, "hoge", "()V");
     env->CallVoidMethod(obj, func);
}
JNIEXPORT void JNICALL naHoge( JNIEnv* env, jobject obj){
     jclass clsj = env->GetObjectClass(obj);
     jmethodID func = env->GetMethodID(clsj, "hoge", "(II)I");
     int retval = env->CallIntMethod(obj, func, 1, 2 );
}

C側からjavaメンバー変数の値取得

例:その関数を呼び出したjavaオブジェクトのメンバー変数mHogeValueの値(int)を取得する関数

JNIEXPORT void JNICALL naHoge( JNIEnv* env, jobject obj){
     jclass clsj = env->GetObjectClass(obj);
     jfieldID fid =
     env->GetFieldID(clsj, "mHogeValue" , "I");
     int hogeValue = env->GetIntField(obj, fid );
} 

C側からjava メンバー変数の値変更

例:その関数を呼び出したjavaオブジェクトのメンバー変数mHogeValueの値(int)に1を設定する関数

JNIEXPORT void JNICALL naHoge( JNIEnv* env, jobject obj){
     jclass clsj = env->GetObjectClass(obj);
     jfieldID fid =
     env->GetFieldID(clsj,"mHogeValue" , "I");
     env->SetIntField(obj, fid, 1);
} 

C側からjava側にint配列を返す

JNIEXPORT void JNICALL naHoge( JNIEnv* env, jobject obj){
    int valuesToTransfer[3] = {1,2,3};
    int len = sizeof(valuesToTransfer) / sizeof(int);
    jintArray array = env->NewIntArray(len);
    if (array == NULL) {
        return NULL; 
    }
    env->SetIntArrayRegion(array, 0, len , valuesToTransfer );
    return;
} 

C側で文字列を受け取る

JNIEXPORT void JNICALL setString(JNIEnv* env, jobject obj,
  jstring javaStringObj )
{
     const char * cstring = env->GetStringUTFChars(javaStringObj, 0);
}

C側で文字列の配列を受け取る

JNIEXPORT void JNICALL setStringArray(JNIEnv* env, jobject obj, jobjectArray javaStringArray)
{
 int stringCount = env->GetArrayLength(javaStringArray);

     for (int i=0; i<stringCount; i++) {
         jstring string = (jstring) env->GetObjectArrayElement( javaStringArray, i);
         const char *rawString = env->GetStringUTFChars( string, 0);
         // Don't forget to call `ReleaseStringUTFChars` when you're done.
         // ....
      env->ReleaseStringUTFChars( string, rawString );
     }
}

初期化(JNI_OnLoad)やその時すべき処理等のサンプル

https://android.googlesource.com/platform/development/+/master/samples/SimpleJNI/jni/native.cpp

2013年12月30日月曜日

Logcatでスペースを含む文字列でフィルタする

Logcatのフィルタ入力欄において、スペースはAND(論理積)としてみなされます。
スペースを指定したい時は\sを使いましょう。

例:
Log.d("hoge", "text A" );
Log.d("hoge", "text B" );

というログを両方ヒットさせたい時

text A|text B
text\sA|text\sB


前者の場合、
"text"と、Aまたは"text"と、Bを含む文字列がフィルタされます。


2013年10月28日月曜日

OpenSL for Android で困ってること

OpenSL for Androidで困ってることをいくつか。
全部、デコードするときの問題です。直接再生する時は違うのかもしれない。

1.VBRのmp3ファイルので、シークが正確でない。
VBRのmp3ファイルのシークの精度が悪い。平気で数秒程度ずれる。
わかりやすい例であh、曲の終わりにシークさせて再生させても、平気で曲長を越えて2~3秒くらいは再生する。
OpenSLを使ってる他のプレーヤーアプリでも同じ現象が確認できるから実装の問題ではないと思う。

対策は・・・今のところみつかってない。
英語で検索してもそれらしい事を言っている人を一人も見ないのは、大した問題では無いからなのだろう。自分が作っているアプリの場合は、これが致命的になるケースがあるので困っているのだが。

2.Galaxyシリーズでのモノラル音声の再生が怪しい。
どう怪しいかというと、普通の端末ではモノラルサウンドでは1チャンネル分がデコードされるのだが、一部のGalaxy端末では、2チャンネル分のPCMが出力される(サンプリングレートが倍になってるのと等価)。
結果的に半分の速度でスロー再生しているような音声が再生されてしまう。
困ったことに全てのGalaxy端末で発生するわけではない。

解決策としては、モノラルのサンプルデータを仕込んでおいて、アプリの初回起動時にデコードサイズが想定されるサイズになるか、倍のサイズになるかを調べれば良い。
倍のサイズになった場合は、常にステレオ音声として再生させれば良い。

これでOK.

・・・・と、思うじゃないですか。
実際にこれでGalaxyS3ではこれで回避できたし、
友人のGalaxyS2( 日本で最新の4.0.3 )でもこれで回避できた。
が、4.0.4なGalaxyS2をお持ちの海外ユーザーさんからは相変わらず直らないとの声。
手動でステレオモードに切り替えてもらったら正常に再生されたそうなのだが、ログを送ってもらうと、デコードサイズは通常サイズ。
正直何がなんだかよくわからない。

4.0.4なGalaxyS2が手に入ったらもう少し追ってみたい。
か、誰か答え知ってたら教えて下さい。

2013年9月3日火曜日

「サーバーへの安定したデータ接続を確立できません」が出て困った

久々に起動したAndroid端末でGoogleアカウントを追加しようとしたら

サーバーへの安定したデータ接続を確立できません

という表示が出てアカウントの追加ができない状態に・・。
いろいろ試した結果、原因は単純に時計がずれているせいでした。
(久々に起動したもんだから時計が1980年1月1日に戻っていたのでした)
時刻を修正して試したらアカウントの追加ができた。