Author: str

FRep – Finger Replayer

FRep2については FRep2サポートサイトを参照してください。

FRep -Finger Replayer-については FRepサポートサイトを参照してください。

お問い合わせ

各トラブルシューティングで解決しない問題や、その他技術的なお問い合わせについては、support[アットマーク]strai.x0.com までご連絡ください。携帯よりメールでお問い合わせの場合は、PCメールの受信を許可するよう設定してください

企業向けのライセンス、操作・設定の自動化/簡易化の要望なども上記メールアドレスまでご連絡ください。

Customizing Character Image – Live Launcher Witch

This section describes the procedures to customize the character image of Live Launcher Witch.

sample chara image PNG (32x56 px, 4 directions x 6 motions  x 3 pattern)1. Prepare PNG character image and rename its filename as “chara.png”. As for the layout, see the instructions below.
2. Copy the chara.png to the SD card of your device, as (sdcard)/strai/chara.png.
3. (After copying, unmount your SD card from your PC to be able to read the file from app.)
4. Set the parameters of the image from Settings of LiveLauncher Witch, Customize | Character Image | Width, Height, No. of Motions.
5. Set the image from Settings of LiveLauncher Witch, Customize | Character Image | Character Image | sdcard/strai/chara.png.
6. Set the display size from Settings of LiveLauncher Witch, Customize | Character Display | Width, Height.
7. (Optional) To change the motion speed, set the frame per second (FPS) from Settings of LiveLauncher Witch, Customize | Character Image | Walking FPS, Staying FPS.

[Preparation of PNG character image]

The size of character should range from 32×32 to 128×128 px, limited its width and height are multiples of 8 px.  The image must have the 3 pattern with 4 directions and motion(s) for animation.  You can put the same image at each section to omit the directions and/or motion(s).  In some case, the Stay check will make the image look better.

1. Decision of Character Size

The character size of the sample image is 32×56 px, which is rather small for high-resolution devices.  You can change the display size from Settings of LiveLauncher Witch, Customize -> Character Display -> Width, Height.  The default setting is double-sized, 64×112 px with the 8bit game sprite like scaling.  The width and height are multiples of 8 px.
2. Decision of No. of Character MotionsLocation of character motions

The sample image contains 6 motions as 6 columns for each animation row.  To use static image (no animation), you need only 1 column.

3. Create the PNG file

For the default image, I used the free software EDGE (in Japanese) to prepare the pixel art PNG with animations.  This edge file will be useful for preparation by using EDGE.

When you create the new image, you must set the size as following size.

[Width] Width of the character x No. of motions
[Height] Height of the charecter x 12

The 12 consists of 3 patterns of Stay/Walk/Boot, multiplied by 4 directions of Left lower/Upper left/Right lower/Upper right.  As for each layout, refer the sample image.

Android 2.1 SQLite3で緯度経度から距離検索

Android 2.1のSQLiteにはsin, cos関数がないため例示されているMySQLでの経度緯度からの距離検索はそのままの形では利用できない。解決のヒントをもとに実装したので要点まとめ。

▼元の公式からクエリに利用できる形へ変換
距離 = C * acos ( sin(lat)*sin(qlat)+cos(lat)*cos(qlat)*cos(lng-qlng) )

[lat, lng] 座標1の緯度経度(DB内を想定) …青字はDB格納時に予め算出できる部分
[qlat, qlng] 座標2の緯度経度(基準位置を想定) …緑字はクエリ投入時に算出できる部分
C=6371 (距離の単位がkmの場合) または 3959 (単位がmiの場合)

cos(a-b) = cos(a)*cos(b)+sin(a)*sin(b) なので、

距離 = C * acos ( sin(lat)*sin(qlat)+cos(lat)*cos(qlat)*(cos(lng)*cos(qlng)+sin(lng)*sin(qlng)) )

acos(x) = y は cos(y)=x なので、

cos(距離/C) = sin(lat)*sin(qlat)+cos(lat)*cos(qlat)*(cos(lng)*cos(qlng)+sin(lng)*sin(qlng))

SQLite内のエントリには緯度経度それぞれのsin, cos値を追加で格納しておけば、検索条件とする緯度経度のsin, cos、cos(距離/C)を使った四則演算で距離を評価できる形になる。

このときのcos(距離/C)値は距離として-1が最も遠く+1が最も近い状態。

遠い(地球の裏側) -1 … 0 (地球の1/4) … +1 (同一の緯度経度)

▼SQLiteへのエントリ登録
1つの座標について sin(lat), cos(lat), sin(lng), cos(lng) をそれぞれ real型で登録しておく。元の lat, lng 値はそれぞれ atan(sin/cos) で求まるが、誤差が問題になる場合はあわせて記録。

// テーブル登録例
create table location ( _id integer primary key autoincrement, dat0 integer, ... ,
 sinlat real not null, coslat real not null, sinlng real not null, coslng real not null);

※JavaのMath関数がラジアン基準なので記録の際には注意。

Math.sin(Math.toRadians(loc.getLatitude()));

▼SQLite用 Location距離検索クエリの作成
上述のテーブルを距離条件で検索する場合は、基準とするLocation (latitude, longitude)を元に検索用のクエリを動的に作成する。

// SQLiteDatabase.rawQuery用クエリ文
public String searchNearQuery(Location loc, double range_km){
	double km_cos=Math.cos(range_km/6371);	// 距離基準cos値
	double radlat=Math.toRadians(loc.getLatitude()), radlong=Math.toRadians(loc.getLongitude());
	double qsinlat=Math.sin(radlat), qcoslat=Math.cos(radlat);
	double qsinlng=Math.sin(radlong), qcoslng=Math.cos(radlong);

	StringBuilder sb=new StringBuilder();
	sb.append("SELECT _id, dat0, ..., ");
	sb.append("(sinlat*"+qsinlat+" + coslat*"+qcoslat+"*(coslng*"+qcoslng+"+sinlng*"+qsinlng+")) AS distcos ");
	sb.append(" FROM location ");
	sb.append(" WHERE distcos > "+km_cos);	// 値が大きい方が近い
	sb.append(" ORDER BY distcos DESC ");	// 近い順に出力
//	sb.append(" LIMIT 10");	// ←↑↓必要な場合追加
//	Log.d("searchNearQuery", sb.toString());
	return sb.toString();
}

▼検索結果からの距離の取得
distcos値をacos角度x単位で距離へ変換。

if(distcos>=1.0) distance_km = 0.0;	// 誤差の都合、同一座標で1.0を超える場合があるため(※)
else distance_km = (6371*Math.acos(distcos));	// miの場合は6371の代わりに3959
// ※厳密には地球の裏側で-1を超える場合もある。

LiveLauncher Witch キャラクタのカスタマイズ

カスタム用サンプル画像(32x56, 4方向x6モーションx3パターン)学習型ライブ壁紙ランチャーLiveLauncher Witchの表示キャラクタのカスタマイズ手順

1. PCなどでキャラクタ画像 chara.png を作成する
2. Android端末のSDカード内 strai/chara.png に配置する
3. (SDカードをPCに接続している場合、PC接続から解除する)
4. Android端末のライブ壁紙 → LiveLauncher Witch → 設定 → 詳細設定 → キャラクタ画像 → SDカード/strai/chara.png

ここで提供している画像およびファイルは、LiveLauncher Witchでの利用に限り自由に改変・配布してかまいません。他の利用目的での転載・配布や無断使用は権利の及ぶ範囲においてその一切を禁じます。

▼chara.pngの準備

LiveLauncher Witchは32×32~128×128(px)までのキャラクタ画像を表示できます。準備する画像は図のように向きとアニメーションを含んだPNG形式ファイルです。向きやアニメーションが不要な場合は、同じ画像を配置したり、歩かないよう設定すれば違和感なく利用できます。

1. キャラクタサイズの決定

図では32×56(px)のキャラクタを使用しています。
このサイズはhdpi以上のAndroid端末にとって小さいため、表示は倍の64×112(px)を推奨しています。ちょうど倍サイズなのでドット絵らしい角点になります。ドット絵らしさが不要な場合は表示と同じキャラクタサイズで画像を作成してください。サイズは縦横とも8の倍数とします。

2. モーション枚数の決定

図では1つのアニメーションにつき6枚のモーション画像を用意しています。アニメーションが不要な場合は1とします。

3. PNGファイルの作成chara.png構成の概要

開発環境ではフリーソフト高機能ドット絵エディタEDGEを使用して作成しました。EDGEを使用する場合はサンプルファイルを参照してください。グリッドサイズをキャラクタサイズに指定するとコピー&ペーストも簡単です。

PNG画像を新規作成する場合には、以下のサイズで作成します。

[横幅] キャラクタ幅 x モーション枚数
[高さ] キャラクタ高さ x 12

高さの12倍の内訳は、[待機/歩き/起動]x[左下/左上/右下/右上]の3×4です。それぞれの配置は図を参照してください。

▼Android端末のSDカード内 strai/chara.png に配置する

以下はPCとUSB接続した場合の手順です。

1. SDカードのマウント

USB接続時や通知バーからUSB接続(マウント)を行います。

2. straiディレクトリの作成と配置

接続した端末を開き、新しく strai ディレクトリ(フォルダ)を作成してその中にchara.pngをコピーします。

3. SDカードのアンマウント(切断)

通知バーからUSBストレージをOFFにして接続を切断します。Linuxでは書き込みを確定するためあらかじめOS側でアンマウントの操作が必要になることがあります。

▼Android端末のライブ壁紙 → LiveLauncher Witch → 設定 → キャラクタ画像設定

ライブ壁紙の設定から画像と表示の設定を変更します。

1. ライブ壁紙の設定を開く

OSバージョンや端末により異なりますが、一般にはライブ壁紙のLiveLauncher Witchを選択すると現れる設定ボタンから開きます。

2. 以下のキャラクタ画像設定を変更する

キャラクタ画像(PNG) → SDカード/strai/chara.png
画像内キャラ幅、高さ → キャラクタサイズの幅、高さ
画像内モーション枚数 → モーション枚数

3. 必要に応じて以下の表示設定を変更する

キャラ表示幅、高さ → 表示するキャラクタサイズの幅、高さ
待機させる → 向きや歩きアニメーションを使用しない場合はONを推奨
位置:横、縦 → 待機させる場合には待機位置の指定を推奨

その他関連する設定項目

アニメーション速度: キャラクタ画像設定 → 歩き時FPS(枚/秒)、待機時FPS(枚/秒)
歩き時の歩幅: 表示設定 → 歩幅(横px)、歩幅(縦px)

ライブ壁紙設定画面のPreferenceScreen階層が黒画面になる

PreferenceActivity#addPreferencesFromResourceからxmlで設定項目を作成した際に、<PreferenceScreen>を入れ子にすると子画面に移動した時に画面が真っ黒になる原因と対処。

▼原因
Android 2.xのバグと、ライブ壁紙向けの設定画面テーマの組み合わせが原因。(2.1で確認)

・Android 2.x系列のバグ: xmlリソースに指定した入れ子のPreferenceScreen子画面の背景が必ず黒(デフォルト)になる問題
http://stackoverflow.com/questions/2615528/preferenceactivity-and-theme-not-applying
http://code.google.com/p/android/issues/detail?id=4611#c12

・ライブ壁紙設定用PreferenceActivity向けテーマ: 半透明の白背景+黒文字

<!-- SDKのライブ壁紙サンプルWall内AndroidManifest.xmlから抜粋 -->
<activity android:label="@string/cube2_settings"
    android:name=".cube2.CubeWallpaper2Settings"
    android:theme="@android:style/Theme.Light.WallpaperSettings"
    android:exported="true">
</activity>

▼対処
・AndroidManifest.xmlの該当する<activity>にandroid:themeを指定しない(=デフォルトの黒背景テーマ)もしくは黒背景のテーマを指定する
・画面毎に個別のPreferenceActivityを作成して親画面から呼ぶようにする ()

コード管理の容易さから前者を推奨。

Android 2.1/3.2 ステータスバー通知の取得

NotificatioinManagerからは現在の通知を取得できないが、AccessibilityServiceを使用すれば他のアプリケーションから通知されるNotifycationをイベントとして取得できる。

▼ステータスバー通知 Notification / NotificationManager の特徴
・NotificationMaganerにNotificationを追加するとステータスバーに通知される
・NotificationにはViewを指定できる
・NofiticationManagerでは追加/上書/削除のみを行える
他アプリの通知を取得できないように制限されている。

▼ユーザ補助サービス AccessibilityServiceの特徴
・他アプリでの操作の一部や通知内容の一部を取得できる
・テキスト入力内容まで取得できてしまうため安易に利用できない
・通常のアプリケーションとは別に設定→ユーザ補助からサービスを許可/実行する必要がある

▼AccessibilityServiceのサンプルコード
・必要最低限のサンプルコード (理解には最良のサンプル)
本家和訳サイト
・Android 3.2で実装したところ、Toastも Notificationとして受け取って自己ループに陥ったので修正

▼AccessibilityServiceからの受け渡し
・SharedPreferencesを介してStringで受け渡す例 (抜粋)
サービスとの通信が不要で、ユーザ補助のON/OFF切り替えを認識せずに受信可能。

public class StrAccessibilityService extends AccessibilityService {

	public static final String SHARED_ACCESS_PREFS="str_access";
	public static final String ACCESS_PREFS_KEY="access_key";

	private SharedPreferences mPrefAccess;
	public static final boolean DEBUG=true;	// 通知のToast表示フラグ

	@Override
	public void onCreate() {
		super.onCreate();
	}

	@Override
	public void onServiceConnected() {
		mPrefAccess = getSharedPreferences(SHARED_ACCESS_PREFS, MODE_PRIVATE);

		AccessibilityServiceInfo info = new AccessibilityServiceInfo();
		info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
		info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
		info.notificationTimeout = NOTIFICATION_TIMEOUT_MILLIS;
		info.flags = AccessibilityServiceInfo.DEFAULT;
		setServiceInfo(info);
	}

	@Override
	public void onAccessibilityEvent(AccessibilityEvent event) {
		int eventType = event.getEventType();
		switch (eventType) {
		case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED :
			if(DEBUG) Log.d("StrAccessibilityService", "Access NOTIFIFY:"+event.getText());
			putPreferences(event);
			break;
		}
	}

	private void putPreferences(AccessibilityEvent event){// Preferenceを変更
		SharedPreferences.Editor editor = mPrefAccess.edit();
		editor.putString(ACCESS_PREFS_KEY, ""+event.getText());
		editor.commit();
	}

}

取得側クラスは SharedPreferences.OnSharedPreferenceChangeListener を implement し、 onSharedPreferenceChanged で取得する。

	public static final String SHARED_ACCESS_PREFS="str_access";
	public static final String ACCESS_PREFS_KEY="access_key";
	private SharedPreferences mPrefAccess;

	@Override
	public void onCreate() {
		super.onCreate();
		mPrefAccess = getSharedPreferences(SHARED_ACCESS_PREFS, MODE_PRIVATE);
		mPrefAccess.registerOnSharedPreferenceChangeListener(this);
	}

	@Override	// StrAccessibilityService#putPreferencesによりコールされる
	public void onSharedPreferenceChanged(SharedPreferences prefs,String key) {
		String access_text = prefs.getString(ACCESS_PREFS_KEY,null);
		// (ここから処理)
	}

Android 2.1でのSQLite FTS3テーブル

SQLiteでFTS3テーブルを構築する際のポイントがいくつかあるようなのでまとめ。
構築済みのテーブルから全文検索用にFTS3テーブルへ移行/FTS3テーブルを追加する場合の注意点リストにも。

▼SQLite FTS3テーブルの特徴
サイズが膨張するためテキスト検索が不要な情報はテーブルを分ける
・FTS3テーブルの値は文字列扱いになり条件に不等号が使えない
_id もTEXTになりPRIMARY KEYですらなくなる → 代わりに docid が自動的に作られる

▼設計
1エントリにテキストと数値が混在し、検索しないテキストが多い場合や数値の条件検索をSQLiteで行う場合はテーブルを切り分ける。

// 通常のテーブル
create table normaltable ( _id integer primary key autoincrement, i_dat0 integer, ... );

// FTS3テーブル (自動的にdocid integer primary key autoincrementが追加される)
create virtual table ftstable USING fts3( stext text, ... );

▼データ管理
設計にもよるが1つのデータを通常のテーブル+FTS3テーブルに分けて登録する場合は、下記の検索方法を使用するため、insert、deleteなどの操作をする場合は両方のテーブルで行う。

public long registerEntry(ContentValues cv) {
	// ContentValues を通常テーブル用+FTS3テーブル用に分割
	ContentValues cv_n=new ContentValues(cv);
	ContentValues cv_fts=new ContentValues();
	cv_fts.put("stext", cv.getAsString("stext")); cv_n.remove("stext");
	cv_fts.put("s_dat0", cv.getAsString("s_dat0")); cv_n.remove("s_dat0");
	cv_fts.put("s_dat1", cv.getAsString("s_dat1")); cv_n.remove("s_dat1");
	return registerEntry(cv_n, cv_fts);
}

public long registerEntry(ContentValues cv_n, ContentValues cv_fts) {
	mDb.insert("ftstable", null, cv_fts);
	return mDb.insert("normaltable", null, cv_n);
}

▼検索
通常のテーブルとFTS3テーブルを _id と docid で参照して両方のデータを含むCursorを取得/Adapter処理できる。

// mDb.rawQuery用検索クエリ例. MATCH部分は*ワイルドカード可
select dt._id, dt.i_dat0, vt.stext
	from normaltable dt, ftstable, vt
	where dt._id=vt.docid AND vt.stext MATCH "Keyword";

 

 

1行メモ

▼ServiceからFLAG_ACTIVITY_NEW_TASKを使わずにActivityを起動する時もPendingIntentを利用

http://groups.google.com/group/android-developers/browse_thread/thread/e95740e776982f89

▼ホーム常駐AppWidget基本サンプル(1.6~): クリックはRemoteViews.setOnClickPendingIntent

http://www.atmarkit.co.jp/fsmart/articles/android10/android10_1.html

▼GIMPでアルファチャンネル付きのPNG作成: カラーモードRGB・レイヤーマスクを作成/編集/適用

http://smileboom.com/tkool/alpha.html

▼開発マシンを移行した後eclipseからデバッグ実行時にエラーが現れる問題

“Re-installation failed due to different application signatures”であれば一旦アプリをアンインストールorシグネチャを旧マシンからコピー

▼タブレットアプリの開発時にhdpiではなくmdpiリソースになってしまう問題

(dpiという意味では正しいので仕様) コード内でリソースにDPIを指定すれば取得できる。

getResources().getDisplayMetrics().densityDpi=DisplayMetrics.DENSITY_HIGH;

▼Serviceが止まりすぎると再起動して貰えなくなる

http://www.swingingblue.net/mt/archives/002768.html

▼自作のAccessibilityServiceが有効かどうかをチェックする

http://stackoverflow.com/questions/5081145/android-how-do-you-check-if-a-particular-accessibilityservice-is-enabled

▼テキストの大きさに合わせてフォントサイズを自動調整するTextView

http://stackoverflow.com/questions/5033012/auto-scale-textview-text-to-fit-within-bounds/5535672#5535672

▼リリース用signed APKをインストールしていると開発版をEclipseから実行してもADTがインストールしないためデバッグできない

いったんアンインストールする必要があるが、データを残すには adb uninstall -k (パッケージ名)

▼PreferenceActivityで現在の設定値をsummaryに表示するメソッド例 setSummaryAll

#onCreate などで setSummaryAll(getPreferenceScreen());

▼PreferenceScreenのsetSummaryによる要約の指定が反映されない

対策はonContentChanged() または getListView().invalidate()

▼logcat read: Invalid argument が現れたら以下のコマンドでadbのログをクリアしてEclipseを再起動

platform-tools/adb logcat -c

▼Toastによるポップアップメッセージ

Toast.makeText(this, "Message String", Toast.LENGTH_SHORT).show();

SQLiteのバージョン差 Android OS 2.1 (SQLite 3.5.9) と 2.2以降 (SQLite 3.6.22)に注意

▼android.database.sqlite.SQLiteMisuseException: library routine called out of sequence 主に複数スレッドからの同時アクセスによるエラー

http://www.sqlite.org/cvstrac/wiki?p=LibraryRoutineCalledOutOfSequence

▼Cursor制限?のためSQLiteの1レコードは1MB以内 [検証]

http://n2works.net/column/pickup/id/82

▼コンテンツデータベースが大きいときにはアプリとは別にダウンロードして利用する [サンプルコード/英語]

http://penguinman-techtalk.blogspot.com/2010/08/loading-large-reference-database-in.html

▼GIMPでアルファチャンネル付きのPNG作成: カラーモードRGB・レイヤーマスクを作成/編集/適用

http://smileboom.com/tkool/alpha.html

Android 2.1でのBuffer速度

Java VMでのBuffer速度ベンチマークを測定している方がいたので、Xperia (SO-01B/Android 2.1)でどれくらいの差があるかを大ざっぱにチェックした記録。ソース(javaのみ)

結果の値は全てmsec. (/L:ByteOrder.LITTLE_ENDIAN, /B:ByteOrder.BIG_ENDIAN)
※Xperia (Android 2.1)のByteOrder.nativeOrder() は LITTLE_ENDIAN

▼領域確保 配列長(32768, 131072)のint[]、IntBuffer、ByteBuffer (*4bytes)の確保時間

領域確保(整数型32,768分) 1回目 2回目 3回目 4回目 5回目
int[] new 1 94 1 1 1
IntBuffer allocateDirect/L 15 4 1 1 2
IntBuffer allocateDirect/B 287 1 2 1 1
IntBuffer allocate/L 2 1 91 1 1
IntBuffer allocate/B 1 1 1 92 1
IntBuffer wrap 8 1 1 0 91
ByteBuffer allocateDirect/L 1 1 2 2 2
ByteBuffer allocateDirect/B 1 1 1 1 1
ByteBuffer allocate/L 69 91 1 1 0
ByteBuffer allocate/B 1 0 92 1 1
ByteBuffer wrap 0 0 0 91 0
領域確保(整数型131,072分) 1回目 2回目 3回目 4回目 5回目
int[] new 98 120 93 91 90
IntBuffer allocateDirect/L 94 96 95 94 144
IntBuffer allocateDirect/B 3 3 3 3 3
IntBuffer allocate/L 1 1 0 1 1
IntBuffer allocate/B 91 91 31 91 91
IntBuffer wrap 92 92 90 90 90
ByteBuffer allocateDirect/L 96 96 93 94 95
ByteBuffer allocateDirect/B 3 3 3 3 3
ByteBuffer allocate/L 91 92 90 90 90
ByteBuffer allocate/B 91 90 90 90 90
ByteBuffer wrap 92 89 90 91 89

メモリ確保なのでGCが動いてあまり数値が一定しないが基本的には高速。またwrap自体は0~1msで行われるが表の値は new int[] もしくは new byte[] の時間も含む。
allocateDirect(/L)とallocate/Bが比較的遅め。確保法/バイトオーダーで速さが入れ替わっている。

▼処理速度 (個別に値をセット/一括コピー)

int[] array, IntBuffer ib, ByteBuffer bb の以下の処理時間を測定。

for (int i=0; i&lt;SIZE; i++) array[i]=i;
for (int i=0; i&lt;SIZE; i++) ib.put(i);
for (int i=0; i&lt;SIZE; i++) bb.putInt(i);
セット速度(整数型32,768分) 1回目 2回目 3回目 4回目 5回目 最長を除いた4回の平均*
int[] new 16 15 17 18 17 16
IntBuffer allocateDirect/L 317 317 345 315 314 316
IntBuffer allocateDirect/B 444 464 442 371 422 420
IntBuffer allocate/L 282 284 311 280 281 282
IntBuffer allocate/B 342 270 759 147 268 257
IntBuffer wrap 62 25 85 63 64 54
ByteBuffer allocateDirect/L 354 268 264 264 264 265
ByteBuffer allocateDirect/B 405 386 246 372 371 344
ByteBuffer allocate/L 56 232 229 230 254 187
ByteBuffer allocate/B 232 220 216 215 137 197
ByteBuffer wrap 217 229 216 216 217 217

値のセットはどのBufferも遅い。

System.arraycopy(array, 0, array2, 0, SIZE);
ib.put(array);
bb.put(bb_src); // bb_srcはByteBuffer.wrap[bytearray2]
コピー速度(整数型131,072分) 1回目 2回目 3回目 4回目 5回目 最長を除いた4回の平均*
int[] new 2 3 2 2 2 2
IntBuffer allocateDirect/L 2 2 2 2 3 2
IntBuffer allocateDirect/B 9 9 9 9 9 9
IntBuffer allocate/L 988 824 862 581 835 776
IntBuffer allocate/B 519 878 270 820 500 527
IntBuffer wrap 12 12 13 12 12 12
ByteBuffer allocateDirect/L 5 4 5 5 5 5
ByteBuffer allocateDirect/B 97 99 94 96 94 95
ByteBuffer allocate/L 94 94 95 39 94 80
ByteBuffer allocate/B 97 95 94 94 94 94
ByteBuffer wrap 94 109 94 94 95 94

コピーであれば allocateDirect(/L) が高速。

*裏でGCが動くなど、極端に遅い外れ値を除くため5回中もっとも遅かった値を除いて4回を平均