numalog

ぬまおうの活動日誌

Archive for the ‘プログラミング’ Category

[AngularJS]controller宣言方法について

with one comment

最近、Webアプリケーション作成のためAngular.js勉強中です。
忘れないように自分用のメモもかねて、使い方の紹介など。

サンプルコードなどでは、

function HogeCtrl($scope) {
    $scope.hoge = {"foo":"bar"};
}

とコントローラーを宣言することが多いと思うのですが、
以下の形で宣言したほうがいいです。

angular.module('Controllers', [])
    .controller('HogeCtrl', function ($scope) {
        $scope.hoge = {"foo":"bar"};
    });

利用側

<script>
    angular.module('app', ['Controllers']);
</script>
<html ng-app="app">
~
<div ng-controller="HogeCtrl">
    <h1>{{hoge.foo}}</h1>
</div>

‘Controllers’という名前のmoduleを宣言、その中にHogeCtrlというcontrollerを宣言しています。
この方法の利点は、

  • functionとしてglobal宣言しなくてよい。スコープをより高次に隠蔽できる
  • module同士の依存関係がわかりやすくなる
  • moduleとして独立するので機能分割しやすく、再利用がしやすい

などです。

基本的にはfunctionをつなげていくというより、moduleとして宣言したコンポーネントをつなげていく方針でコーディングするほうが、可読性、メンテナンス性を上げることができるかと思います。
angular.jsのチュートリアルを一通りやり、実際の制作に取り掛かるとき、まずやるべきはmoduleの概念の理解だと感じました。


Written by numa

9月 25th, 2013 at 2:53 pm

Androidアプリ開発tips#2 ダイアログの表示について

with 2 comments

  • Dialog.show()は避けるべき

入門書なんかだと、ダイアログ表示するために、以下のようなコードを使うことが多いです。

    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
    Dialog dialog = alertDialogBuilder.create();
    dialog.show();

結論から言うと、これは絶対に避けるべきです。
このソースコードにした場合、ユーザーからの閉じる操作、またはdialog.dismiss()によって適切にダイアログを閉じないと、リーク例外が出るからです。
つまり、これら2つ以外の、予期せぬ事態によってダイアログが閉じられたときエラーとなってしまいます。

そんなのってあるの?と思われるでしょうが、一つ例を挙げると画面回転があります。
Androidでは画面回転させると、いったんActivity破棄→再起動というプロセスが行われるのですが、このActivity破棄の際には画面に出ているダイアログは強制破棄されます。
つまり、ダイアログ回転に対応させるようなソースコードを一切書いていない場合、上2つの終了ケースに当てはまらないので例外となってしまうということです。
具体的に言うと、

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
    }

なんてものを書かなきゃいけないわけです。 1つならばいいのですが、複数ダイアログを使うアプリではその分書く必要があるし、   ダイアログの後処理忘れしてActivityが落ちるなんてことは、これ以外にも多々ありえるので、非常にカオスになりやすいです。
(プログラムのミスを除いても、メモリ不足でシステムが勝手にバックグラウンドActivityを落としたり等)
長く開発をしていると、「~ has leaked window」 というWindowLeakedエラーを一度は見たことがあるかと思いますが、大体は自前でViewやDialogの管理をしていたときに、適切な後処理が出来ていなくて発生するものです。

ではダイアログを使いたい場合どうするかというと、

  1. Activity#onCreateDialog, Activity#showDialog(int id)による管理をする
  2. Fragmentを使う

の2つのダイアログ表示方法があります。
2に関しては、2.x系ではデフォルトでは使用不可で、サポートライブラリを入れる必要があるので、とりあえずここでは1を紹介します。

厳密にはちょっと違いますが、イメージとしては、

  • Activityで、onCreateDialogをoverrideし、あらかじめ使う可能性のあるダイアログを、IDを割り振って登録しておく

  • Activity#showDialog(int id)で、登録してあったそのIDのダイアログをshowする

という流れになります。

具体的なコードは、Activity内で、
登録側

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case 0: // ダイアログidを割り振っている
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
      Dialog dialog = alertDialogBuilder.create();
      return dialog; // 表示したいdialogをreturnする 
        default:
            return null;
        }
    }

使用側 onCreateや、他のメソッド内で

    this.showDialog(0);
    //onCreateDialog内で、0番IDを割り振ったDialogを表示<br />
  //具体的にはonCreateDialog(0)を呼んだときの戻り値となるDialogを表示している
    //一度showしたdialogは、dismissしてもインスタンスの使いまわしが行われる。
    this.dismissDialog(0);//基本はこっち。showDialogを再度すると、前のダイアログが使いまわされる
    this.removeDialog(0);//手動でダイアログの消去と、ダイアログ使い回しを破棄をしたい場合。
となります。

この方法で表示した場合、上記の回転処理や、予期せぬ終了を、Activity側がある程度自動で管理してくれるので、エラーが出る確率がぐっと減ります
慣れていないと回りくどく感じるかもしれませんが、Dialog.show()をするよりはるかにお勧めな方法です。
dialogに引数や値を渡したい場合は、代わりにonCreateDialog(int id, Bundle data)をoverrideし、showDialog(id, data)などと、bundleとして値を渡すことになります。
ただし、これは要求APIがAPI level 13で、IDのみ(API level 8)と比べて高くなってしまうので注意です。


Written by numa

6月 14th, 2013 at 2:48 am

Posted in プログラミング

Tagged with ,

Androidアプリ開発tips 開発環境整備について

without comments

自分が経験したり、開発をしていて思ったことを述べていきます。

  • 開発、デバッグは基本的に実機がおすすめ

エミュレーターだと速度面で不安が出たり、また現実のデバイスとPCモニタ越しでは、UIの受ける印象が違います。
他にもエミュレーターだとPlayStoreなど一部プリセットアプリが入っていなかったり、
現実のデバイスが持っている、物理的ハードウェアの影響、テストが難しかったりします。(bluetooth、wifi、3G回線でのテストなど)

安タブレットでもいいので、とにかく実機を使うべきです。

Androidは同じバージョンでも、端末やメーカーによって挙動が変わるので、エミュレーターで動いたからと言って実機で動くとは限りません
あくまで実機で持っていないバージョンでの、軽い動作検証程度で使うべきです。

たとえばエミュレーターでありがちな見落としで、manifestにconfigChangesを設定していないせいで、実機だとローテーションしてしまいonCreateやり直し、そのせいで予期せぬ挙動になってしまう
とかがあり得ます。このようにエミュレーターだとすぐにおきなくても、実機でならすぐに起きて気づける現象もあります

  • どうしてもエミュレーターを使いたいときは,HAXMを使う。

IntelCPU限定ですが、HAXMというのをインストールするとエミュレーターの速度が劇的に改善します。
必ず、自分のPCで使えるかを試してみるべきです。   http://note.chiebukuro.yahoo.co.jp/detail/n134146
HAXM有効かについて、よくまとまっている記事ですのでおすすめです。

これ以外にもVirtualBoxで動かす という手段もあるそうなのですが、自分は試したことがありません。

  • コンソール(コマンドプロンプト)からadbを使う

Windowsでしたら、ぜひadbへパスを通しましょう。
通し方は、
http://www.techmaru.net/wordpress/20100516/androidsdk/
がよくまとまっていておすすめです。

adb install (apkファイルをusb経由でインストール) や、adb connect(ipを指定して、ネットワーク越しにandroidに接続できる)、adb device(接続ができているデバイス一覧の取得)や、logcatを拾ったり・・・
と開発に便利なことがいろいろとできます。

  • 出来ればwindowsでの開発は避ける

なぜかというと、Windowsではandroidの実機1台ごとに、いちいちメーカ製ドライバを入れなくてはいけないので、複数端末で検証するとき非常にめんどくさいです。
MacやLinuxでは必要なく、基本的にただつなげるだけで、全デバイスが認識されます。

また特にandroidだけの話ではなく、文字コードやwindowsの特殊なファイルパス、gitなど便利なソフトが大体windows対象ではない、ターミナルの使い勝手 etc…などの理由で、
基本的にプログラミング開発環境はMacやLinuxなど、Unix系を使用することをお勧めします。

と言っておきながら自分はwindowsだけど…


Written by numa

5月 4th, 2013 at 12:52 am

Posted in プログラミング

Tagged with