Home

svartalfheim.jp

リトルエンディアンとビッグエンディアンの違い

リトルエンディアンとビッグエンディアンの違いについて、
よくわかっていなかったので調べて見ました。

エンディアンとはメモリに値を保存する時に、どういった順番で保存するかを定めた方式のことを指します。
では具体的に考えてみましょう。

まずプログラムで値を保存する時、コンピュータのメモリは1バイト単位で記憶していきます。

しかしながら、保存したい値が複数バイトの値、たとえば0×12345678(16進数)を保存したいとすると、
これを保存するときは値を分割して保存しなければなりません。
ではどういう順番で入れていいのか、ここでエンディアンが登場します。

ビッグエンディアン

  • メモリアドレス0:0×12
  • メモリアドレス1:0×34
  • メモリアドレス2:0×56
  • メモリアドレス3:0×78

リトルエンディアン

  • メモリアドレス0:0×78
  • メモリアドレス1:0×56
  • メモリアドレス2:0×34
  • メモリアドレス3:0×12

※1バイトは8ビット(2^8)なので16進数(1ケタが2^4)だと2ケタ分保存できます。

上位バイトから順にメモリに入れるのがビッグエンディアン、
下位バイトから入れるのがリトルエンディアン、AndroidのDalvikVMだとリトルエンディアンが標準のようです。

参考:http://ja.wikipedia.org/wiki/エンディアン

AndroidでCanvasにキレイに拡大縮小した画像を描画する方法

Canvasに拡大縮小した画像を描画する方法は、
Matrixをつかってscaleを調整した画像をCanvasに描画するのが一般的かと思います。

ところが、Matrixでscaleを調整した画像はエッジのところがジャギーっぽくになってしまいました。

そこで、PaintのAntiAliasをオンにしてみたり試して見ましたが、あまり変わりませんでした。
日本Androidの会ではLanczosやBicubicを実装して試してみた方もいらしゃったようです。
画像をきれいに縮小する方法

しかし、ImageViewにBitmapを入れて拡大縮小してもあまりジャギーが気になったことがないのを思い出し、
ImageViewのonDrawの実装を眺めていると以下のことに気づきました。

Canvas.drawBitmap()ではなくBitmapDrawable.draw()で描画している。

さらにBitmapDrawable.draw()の実装を見てみると、
BitmapShaderを使ってレンダリングしているようですが、
要はBitmapDrawableを使えばキレイに拡大縮小した画像を描画できることがわかればよしとします。

実際に描画するコード


//Android2.1
protected void onDraw (Canvas canvas){
    //現在のセーブカウントを保持(カウント=0)
    int count = canvas.getSaveCount();
    //セーブ(カウント=1)
    canvas.save();

    //ResourceからBitmapを生成
    Bitmap bitmap = BitmapFactory.decodeResource(getResource(),R.drawable.icon);
    //BitmapからBitmapDrawableを生成
    BitmapDrawable drawable = new BitmapDrawable(bitmap);
    //drawableの描画領域設定(必須)
    drawable.setBounds(0,0,drawable.getBitmap().getWidth(),drawable.getBitmap().getHeight());
    //bitmapを移動、回転、拡大縮小したい場合はその情報を持ったMatrixをわたす
    canvas.concat(matrix);
    //canvasに描画
    drawable.draw(canvas);

    //リストアする(カウント=0の状態に戻す)
    canvas.restoreToCount(count);
}

はじめにcanvasのセーブカウントを保持しているのは、
上記のViewが仮に子要素を持っていた場合、その子要素内で描画処理をしても、
Canvasの状態を正しい状態に保ってくれるはずです。

下図は上記コードを利用して出力したもので、

  • 画像を2倍にしBitmapDrawableで描画したもの(上)
  • 画像を2倍にしdrawBitmapで描画したもの(真ん中)
  • なにもしていないもの(下)

になります。
BitmaDrawableがキレイに表示されているのがお分かりいただけると思います。

画像をクリックで拡大
device

フェイルファスト(フェイルファースト)とは?

エラーが起きた時ではなく、エラーが起きる可能性が発生した時点でエラーにすること。

らしい。

Unable to open sync connection! と言われたら

EclipseにAndroid adbいれて開発していたら、
下記のような文言が表示され、アプリが端末にイントールできなくなりました。

Failed to upload XXXXX.apk on device 'XXXXXXXXXXXXXXXXXXX'
Unable to open sync connection!

試しにEclipseを再起動させてみましたが、
直らなかったので調べてみたところ下記の記事を見つけました。

Stackoverflow
Android adb “Unable to open sync connection!”

この記事によると
端末のUSBデバックモードを一旦解除し、再有効化するのが解決策のようです。
実際、試してみたところ、問題が解消されました。

Android開発でRの参照がおかしくなったときに直す方法

EclipseにADBプラグインをいれて開発するととても便利ですが、
どうもXMLレイアウトエディターの挙動がおかしいみたいです。

私の環境ではXMLでレイアウトを組んだ後、ViewのIDなどを書き換えたりすると、
時々ですが、R.id.*の参照がおかしくなり、子階層のViewが帰ってきたりしてClassCastExceptionなどが発生してしまいました。

解決方法は簡単で、

  1. Eclipseのプロジェクト・エクスプローラー上にあるプロジェクトをリフレッシュ
  2. Eclipseのメニューのプロジェクト>クリーンで該当プロジェクトを選択後に実行
  3. Rファイルが削除され、再生成されます

あとはプロジェクトをビルド>実行すれば正しく動くはずです。

AndroidでActivityのThemeをDialogにしたときに画面いっぱいに表示するやり方

AndroidのActivityのthemeをTheme.Dialogに設定して表示すると、
中心に小さく表示されてしまいますが、これを画面いっぱいに表示する方法をまとめます。

1)まずマニフェストファイルでActivityにテーマを設定します。
※Activityのlayoutファイルに設定しても効かないようです。

 <activity android:name=".activity.DialogActivity" android:theme="@android:style/Theme.Dialog">

2)ActivityのonCreateで表示設定を書き換えます。

public class DialogActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.popup);

		LayoutParams params = getWindow().getAttributes();
		params.width = LayoutParams.FILL_PARENT;
                params.height = LayoutParams.FILL_PARENT;
		getWindow().setAttributes(params);
	}

これで画面いっぱいに表示されるとお思います。

情報元:

http://stackoverflow.com/questions/2634850/android-dialog-width

Androidで共通のレイアウトXMLを使う方法

いくつかの画面レイアウトで共通のパーツ、例えばヘッダーやフッターといったもの、を指定するには<include />を使います。

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" android:orientation="vertical">
  <include layout="@layout/header" />
</LinearLayout>

res/layout/header.xml

<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
    <TextView android:id="@+id/textView1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:text="@string/text_title">
  </TextView>
</FrameLayout>

※Android2.2をベースにしています。

あと私のEclipseの環境だけかもしれませんが、includeタグを書くとEclipseのレイアウトエディターでXMLエラーが起きますが、
Eclipseを再起動すると直ったりします。

詳細についてはリファレンス(英)をご参照ください。
日本語訳のリファレンスはこちらです。

AndroidでインラインFlashをフォーカスさせる方法

AndroidのWebViewでFlashを表示すると、
デフォルトだと一度Flashの部分をタッチしないとタッチ操作が有効になりません。

解決方法としては、
Javascriptのfocus()を使って強制的に有効化します。

window.onload = function(){
  var swf = document.getElementById("flashContent");
  if(swf){
   swf.focus();
  }
 };

フルFlash(SWFを直接開く)の場合は必要ないです。

Flashの同じインスタンスにMouseEventとTouchEventを併用する

Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
addEventListener(TouchEvent.TOUCH_END, onTouchEnd);

addEventListener(MouseEvent.MOUSE_DOWN,onMouseBegin);
addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
addEventListener(MouseEvent.MOUSE_UP,onMouseEnd);

こんなふうに書いてAndroid向けFlashをPCでデバッグしていて気づいたのですが、
MouseEventとTouchEventを併用していると、
Android上でカックカクになってしまいます。

ですのでこの場合は、Multitouch.supportTouchEventsを取得して分岐させましょう。

Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

if(Multitouch.supportsTouchEvents){
    addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
    addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
    addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}else{
    addEventListener(MouseEvent.MOUSE_DOWN,onMouseBegin);
    addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
    addEventListener(MouseEvent.MOUSE_UP,onMouseEnd);
}

Flashの容量を簡単に増やす方法

あまりないかもしれませんが、
「Flashで容量別の負荷をチェックしたいので容量別にswfください」
とか言われちゃった場合に簡単に容量を増やす方法をご紹介したいと思います。

まず、一番低い容量に合わせてFlashを作成します。
仮に、50kbと100kbを用意する必要があるとします。
50kbはあるので100kbまで50kb分の容量が必要になりますね。

そうしたら、大きな容量の画像(例えば1MBなど)を用意します。
それをPhotoshopの画像解像度で50kbになるぐらいまでリサイズします。
※画像保存時に目標容量になっているか確認しましょう。

そのリサイズした画像を作成したflaのライブラリにいれます。
その画像のプロパティをひらいて、リンケージのクラスとして書き出す、1フレームに書き出しにチェックします。
おそらくBitmapDataを基底としたクラスになると思います。

そしてflaをパブリッシュすると50kb追加されて100kbになったswfが出力されます。

役に立つ時が来るのかわかりませんが、以上です。

Home

Search
Feeds
Meta

Return to page top