2012年12月23日日曜日

A Simple Table Talk 公開

RailsやらAndroidやら不穏な話を最近してましたが、久々にアプリ公開しました

ごくごくシンプルなチャットアプリ A Simple Table Talk


です。

特徴はとにかくシンプルな事?文字だけのチャットです。

他?

・・・考えときます。

2012年12月17日月曜日

AndroidでSingletonパターンをやりたい


謎の何か。

さて、下記の記事、android開発では基本らしいのですが知らない人はびっくりするんじゃないでしょうか?

http://mobileapplication.blog.fc2.com/blog-entry-2.html
http://mobileapplication.blog.fc2.com/blog-entry-3.html

端的に言うとAndroidではメモリ不足等の場合に、生存中のActivityのメンバ変数が勝手に開放される場合がある、って事ですね。

自分も知らなかったのですが…
Androidアプリを開発したての頃に頻発してた原因不明の例外はこれだったみたいです。

でもまあ、良く見りゃちゃんとDeveloper's Guideにも載ってます。

http://developer.android.com/guide/components/activities.html#SavingActivityState

読んでねぇ。
もちろんそこまで読んでねぇ。
最初に言って欲しいわそれは。

そもそも普通にソフト勉強してくと「変数は値が保証される」って半ば無意識に前提にしちゃうと思うんですが、正直その前提というか価値観が崩れる衝撃でした。おおげさ?

しかしメンバ変数についてはユーザーにコールバックという形で通知が来るので百歩譲って良しとしましょう。(その対応として分かりきった手続きを毎回アプリ設計者に実装させる意図はよく分かりませんが・・・)

しかしstaticに至ってはいつ消去されるかすら分からない模様。
ざ、斬新すぎじゃよ?

これの意味する所は、AndroidアプリでSingletonパターンは使えないって事ですよねそうですよね違いますかね?

Androidアプリでは、オブジェクトの生存を保証するものはActivity、という事だと言えそうです。つまり設計上Sigletonなインスタンスが存在するのであれば、それは常にrunningなActivityから参照されている(かつ適切にonSaveInstanceState()/onRestoreInstanceState()されている)必要があるわけです。

もはやSingleton"パターン"ではないですね…

なお、詳細はDeveloper's Guideを見てもらうのが良いのですが、メンバ変数の退避はBundleインスタンスに対して保存する形を取っています。つまり、基本型(intとか配列とか。Stringも基本みたいなもので)か、ParcelableもしくはSerializableなクラスでないといけません。好き勝手にオリジナリティー溢れるクラスやら作りまくってActivityにぶらさげまくってると破綻するって事になるので注意した方が良いですね。

2012年11月20日火曜日

AndroidでJSON取得

取得できるものがJSON ArrayなのかJSONなのか分かった上で切り替えれば良いのですが、一つの内部関数なんかで処理しちゃいたい場合事ありますよね?(強引)
その場合、下記のような関数を使う事で


Arrayだった場合 : そのままJSONArrayとして取得
Objectだった場合 : 要素として一つだけJSONObjectが含まれたJSONArray
それ以外 : 要素0のJSONArray


として一括でArrayとして扱えます。

private JSONArray convertJSONArray(String jsonString) {
    JSONArray ret=null;
    try {
        ret = new JSONArray(jsonString);
        Log.d(TAG, "convertJSONArray : Array");
        Log.d(TAG, "convertJSONArray : ret = "+ ret.toString());
        return ret;
    } catch (JSONException e) {
        ret = new JSONArray();
        try {
            JSONObject json = new JSONObject(jsonString);
            ret.put(json);
            Log.d(TAG, "convertJSONArray : Object");
        } catch (Exception e1) {
            Log.d(TAG, "convertJSONArray : Fails");
        }
        Log.d(TAG, "convertJSONArray : ret = "+ ret.toString());
        return ret;
    }
}
まあえばって公開するほどのコードでも無いんですが、いちいちArrayとObjectを切り替えるのがコード上面倒だったもんで、ちょっと悩みました。 なのでせっかくなんで公開しておきます。

2012年10月15日月曜日

てんやのなぞ


(絵と本文は関係あってこれはおれがてんやで天丼なす乗せを食べている所です。もちろんウソです)


てんやではいつもボーカルなしのカラオケがBGMでかかってる

2012年10月4日木曜日

逃亡編

(例によって絵と本文は関係ありません)
前編: herokuでform_tagの:remote => trueが動かない の続き

結論から行くと、なんとかなりました。
端的に言うと

:remoteの代りにformのactionでjQueryを使用してajaxを実行

です。

はい。逃げました。


そ、Solutionが多数用意されているというのもRailsの柔軟性の高さですね。
とかなんとか。

具体的には

view/layoutで参照されているlayout(一般的にはapplication.html.erb)に下記を定義
var doPost = function (url) {
    $.ajax({
    url: url,
    type: "post",
    data: "comment="+$("#comment").val(),
    dataType: "script"});
};
$("#comment")はjQueryによるSelectorです。
<% form_tag ... %>~<% end %>中に
<%= text_field_tag :comment %>
があれば、id="class"で上記のSelectorは正しく動く、はず。

で、あとは、form_tagのactionから上記のdoPostを呼ぶようにすればOK
<%= form_tag ("javascript: doPost(\"/sessions/\"") do %>
本当は、:remoteと完全に同じ挙動にするためには以下にしたかった

<%= form_tag ('#', :onsubmit => "doPost(\"/sessions/\"); return false;") do %>
でもやっぱり、form_tagが第二引数を取ってくれないので相変わらずエラーになるので逃げた。


逃げるが勝ち

2012年9月14日金曜日

てんやのTips

ご存じみんな大好き「てんや」のTips紹介

企画、期間限定物はちょっと割高なので天丼をベースにカスタマイズするのが基本です。 

おれの基本は天丼+お好みナス乗せ。560円。 

また、定食にすると、天汁で食べた後、テーブルにある天丼のタレで小天丼も楽しめておトクです。

しかし定食にすると650円・・・ ま、迷うんじゃよ。

2012年9月13日木曜日

herokuでform_tagの:remote => trueが動かない


(絵と本文はちょっとだけ関係あります。無力感とか)


更新していない間、色々ありまして今はRuby on Railsをherokuで動かしてます
・・・何があったんじゃろか?
で一個どうしても解決できない問題があるのでここに挙げておこうと思います

[現象]

以下のhelperがherokuで正しく動作しない(実行時エラー)
<%= form_tag ('/sessions', :remote => true) do %>
ローカルのrails上では正しく動作している

[エラーの詳細]

% heroku logs
:
2012-09-11T03:50:31+00:00 app[web.1]: ActionView::Template::Error (/app/app/views/tables/_form.html.erb:1: syntax error, unexpected ',', expecting ')'
2012-09-11T03:50:31+00:00 app[web.1]: ...nd=  form_tag ('/sessions', :remote => true) do @output_...
2012-09-11T03:50:31+00:00 app[web.1]: ...                               ^
:
要は第二引数が有ることがダメだと言っているみたい。
一方ローカルでは期待通り下記のように変換され、正しくリクエストが発行できる
<form accept-charset="UTF-8" action="/sessions" data-remote="true" method="post">

[分かっている事]

% bundle status
% heroku run bundle status
の差分は以下の通り。後者は意図通りなので実質bundlerのみ。これはhelperの動作とは関係ないはず・・・
11c11
<   * bundler (1.1.5)
---
>   * bundler (1.2.0)
28a29
>   * pg (0.14.1)
41d41
<   * sqlite3 (1.3.6)

ちなみにheroku側のGemはこんな感じ。Railsは3.2.8なので問題ないはず・・・
* actionmailer (3.2.8)
* actionpack (3.2.8)
* activemodel (3.2.8)
* activerecord (3.2.8)
* activeresource (3.2.8)
* activesupport (3.2.8)
* arel (3.0.2)
* bcrypt-ruby (3.0.1)
* builder (3.0.0)
* bundler (1.2.0)
* coffee-rails (3.2.2)
* coffee-script (2.2.0)
* coffee-script-source (1.3.3)
* commonjs (0.2.6)
* erubis (2.7.0)
* execjs (1.4.0)
* hike (1.2.1)
* i18n (0.6.1)
* journey (1.0.4)
* jquery-rails (2.1.1)
* json (1.7.5)
* less (2.2.1)
* less-rails (2.2.3)
* libv8 (3.3.10.4)
* mail (2.4.4)
* mime-types (1.19)
* multi_json (1.3.6)
* pg (0.14.1)
* polyglot (0.3.3)
* rack (1.4.1)
* rack-cache (1.2)
* rack-ssl (1.3.2)
* rack-test (0.6.1)
* rails (3.2.8)
* railties (3.2.8)
* rake (0.9.2.2)
* rdoc (3.12)
* sass (3.2.1)
* sass-rails (3.2.5)
* sprockets (2.1.3)
* therubyracer (0.10.2)
* thor (0.16.0)
* tilt (1.3.3)
* treetop (1.4.10)
* twitter-bootstrap-rails (2.1.3)
* tzinfo (0.3.33)
* uglifier (1.3.0)


・・・全然分かりません。
じ、次回は解決編じゃぜ?!