AndroidStudioをVimキーバインドで利用する

Android StudioにはVimプラグインがあり、これを導入することでVimキーバインドでの入力が可能になります。

私はVim小学1年生くらいのレベルですが、そのレベルでもVimを使わない場合と比べてプログラミングが捗るなと思っています。

インストール方法は簡単で、Android StudioのメニューからPreferencesを開き、Pluginsを選択、IdeaVimというプラグインのインストールボタンを押すだけです。

Vimプラグインのインストール

タグなどの書き換えが簡単

Vimを利用することで便利になったことの1つに、タグなどの書き換えが非常にやりやすくなったことが挙げられます。

例えばandroid:layout_width="match_parent"のmatch_parentをwrap_contentに変更しようと思った時。Vimを使う前の私は、match_parentをマウスで選択肢てバックスペースキーで削除する、もしくはカーソルを最後に持って行ってバックスペースキーを連打して削除していました。

マウスを使う場合は余計なダブルクォートまで選択してしまうこともあり、微妙にイライラしてしまいます。バックスペースキーで削除する場合は、消さなくてよいところまで削除してしまい、Ctrl+zで取り消しをするとまた最初から消し直しになることがしょっちゅうありました。とても効率が悪いです。

Vimを使えば、キャレットをダブルクォートの中のどこかに置いてci"と入力するとmatch_parentが消えて書き換えができるようになります。なんとスムーズなんでしょう!

私がVimを便利だなと実感し始めたのは、この機能を知った頃からです。

慣れるまでは大変かもしれない

まったくVimに触ったことのない人だと、慣れるまでが大変かもしれません。私も最初の頃はしょっちゅう間違えておかしなことになっていました。文字を入力しようと思ったら入力できない(挿入モードに入っていない)、カーソルの動かし方がよく分からず、lキーを押して一文字ずつカーソル動かしていたり。慣れるまでVim不便すぎと思ってました。

ただある程度Vimの機能を覚え始めると、その魅力の虜になります。Vimがプログラマーに人気というのも頷けます。「範囲選択? マウスでやった方が早いじゃないか」とずっと思っていたのですが、いざVimを使ってみると想像以上に快適です。キーボードとマウスを行き来するのがこんなに邪魔だったなんて思いもしませんでした。

Android StudioでVimプラグインを導入すれば、マウスでの操作も併用できます。Vim触ったことないという人は、とりあえずAndroid StudioでVimに触れてみるのもいいのではないでしょうか。

ペーパープロトタイピングをまずやろう

アプリを開発する上で、コーディングを始める前にペーパープロトタイプを作るといろいろなメリットを享受できます。

  • どんな画面が必要になるか検討できる
  • 作り終わってから使い勝手の悪いところに気づいて、実装をやり直す事態を未然に防げる可能性がある
  • 必要な機能の絞り込みができる
  • 作ろうとしているアプリのイメージがはっきりしてくる
  • などなど

デザインに疎いとどうしてもコーディングを優先してしまいがちです。画面設計よりシステムを作っている方が性に合ってますし。ついついデザインを後回しにしてしまいます。

しかしその作り方をすると、アプリ完成したけれど残念な見た目だったり、使い勝手が悪くて使えないアプリになってしまったりしているかもしれません。それを後から直そうとすると、せっかく実装したシステムも作りなおしになる可能性もあります。せっかく作ったコードを、使い勝手が悪いからと泣く泣く切り捨てることになったら、目も当てられません。

POP

ありがたいことに、ペーパープロトタイピングを簡単に行うことのできるツールが世の中には存在しています。

POPというアプリを利用すると、紙に書いた画面デザインにいとも簡単に動きをつけることができます。ここを押したらこの画面に移動して・・・なんていうのが簡単に作れて非常に便利です。

Android版のPOP2.0だとジェスチャーを設定する項目があるものの、設定しても動かなかったり、スマホで撮影した画面を削除しようとしたらゾンビのごとく復活してきたりと、使い勝手が微妙なところがあります。私の使ってる端末固有の問題なのかもしれませんけれども・・・。

ただこれがあるだけでも画面の動きのイメージがつきます。この画面遷移は使いづらいとか、こういう画面も用意しないといけないなというのが簡単に分かります。このアプリ、便利なのは間違いありません。

Androidからだけでなく、パソコンのブラウザやiPhoneなどからも使うことができるので、ブラウザで編集してスマホで動作を確認するなんて使い方ができます。

POPブラウザからアクセス

テンプレート

紙にアプリのデザインを書くのに、さり気なくネックなのが画面を描画するところです。画面の外枠です。私はこれが面倒くさくて、画面を紙に書けないでいました。

枠を決めるのが難しいのであれば、最初から用意されているものを利用すればいい。そこで私は、iPhone5のワイヤーフレームに使えるアイデアシートをイラレで作りましたさんで公開されているアイデアシートを利用させていただきました。

現在はリンク切れで見れなくなってますね・・・。

iPhone5向けのテンプレートではありますが、画面の比率はAndroidとそう大差ありません。画面の外枠が決まっているだけでも、やりやすさが段違いです。

どう実装するかはとりあえず考えない

とりあえず考えるのは、ボタンをどこに置いて、どの画面に移動するのかだけに絞った方がいいと思います。できるだけシンプルに考えるのが大事です。どうやってコーディングしようかと考えだすと、何も書けなくなってしまいます。

実装方法を考えながらやってしまうと、実装しやすさを優先するあまりに使い勝手が犠牲になるのが悲しいです。とりあえずアイデアシートを印刷して、どしどし書くべしです。書いていればいいアイデアが浮かんだりします。紙に書くだけなのでやり直しも簡単ですしね。

せっかくアプリを作るのであれば、多くの人に使ってもらいたいです。そのためにも、せめて使い勝手がよくなるような努力はしておきたいですよね。

Genymotionを導入してエミュレータの起動待ち時間を短縮する

アプリ開発をしていてバカにならないのが、デバッグにかける時間です。頻繁にエミュレータを起動して動作確認を行うわけですが、デフォルトのエミュレータ(Android SDKのエミュレータ)はとにかく起動が遅いです。さらに動作ももっさりしていて、お世辞にも動作確認しやすいとはいえません。

そこで動作確認の時間をできるだけ短縮するためにも、Genymotionを導入しておくことをおすすめします。起動も早く動作もスムーズなので、デフォルトのエミュレータを使うのが馬鹿らしくなります。

私の環境で実際に両者を比較した動画を撮ってみました。

Genymotionをインストールする

Genymotionを利用するためには、ユーザー登録が必要になります。

また、エミュレータを動かすために別途Virtual Boxが必要になります。

端末を登録する

Genymotionをインストールできたら、端末の登録を行いましょう。Genymotionは実在する端末のエミュレーションを行うものなので、よく使う端末をとりあえず登録しておけばいいと思います。

サポートするAndroidのバージョンに合わせて登録しておくといいでしょう。私はとりあえず、Android2.3の端末と、自分の持っているGaraxy S3を登録しています。

端末の追加はそんなに難しくありません。予め用意されている端末から、エミュレーターとして使いたいものを選択するだけです。

Genymotionで端末の追加

Genymotion端末の選択

Genymotion端末の表示名を決める

後はダウンロードを待つだけ

Android Studioでプラグインを導入する

Android StudioからGenymotionのエミュレータを起動するためにも、Genymotionのプラグインも一緒にいれましょう。別に入れなくても使用に問題はありませんが、入れておいたほうがエミュレータの起動が捗ります。

GenymotionPluginからの端末起動

こんな感じでAndroid Studioから起動しやすくなります。

インストールの仕方はAndroid StudioのPreference > PluginsからGenymotionを探してインストールするだけです。そうすることでAndroid Studioの右上にGenymotion用のアイコンが追加されます。

Genymotion Pluginのインストール

万能ではないものの使わないのは損

Genymotionではデフォルトのエミュレータと比較して、画面サイズやAndroidのバージョン、SDカードの有無など細かなところまでカスタマイズすることができません。特にFreeライセンスでは利用できる機能に制限があるため、Android SDKのエミュレータを完全に置き換えるものではありません。

ですが基本的なデバッグ・動作確認にGenymotionを利用することで、アプリ開発における動作確認の時間を短縮することができると思います。基本的にはGenymotionを使うようにすれば、開発がだいぶ捗るのではないでしょうか?

ProGuardによる難読化って具体的にはどうなってるのだろう

確認方法

手順としては、ProGuardを適用していないapkファイルと、適用したapkファイルの2つを用意しました。そしてリバースエンジニアリングを行い、apkファイルからソースコードの抽出を行い確認を行いました。

ProGuard適用前

ProGuard適用前

こちらがProGuard適用前のソースコードです。ほぼ自分で作ったソースコードのままで、Android Studioで作り上げたソースコードと大差ありません。

ProGuard適用後

ProGuard適用後

こちらはProGuardを適用した後のソースコードです。一部の変数名やクラス名、メソッドなどがa,bといった意味のない文字列に置き換えられています。

全てが書き換わっているわけではなく、forやifなどの命令文はそのままですし、解読しようとしてできないレベルではありません。

ProGuardのお仕事

私は難読化というからには、もっと複雑な変換が行われているのだとばかり思っていましたが、意外にシンプルな難読化でした。確かに読みづらくはなっていますが、解析しようと思えばやってできないレベルではありません

ProGuard適用前後の比較

変数名やメソッド名等は、一部意味のない文字列に置き換えられているものの、処理の流れなどはそのままであるため、アルゴリズムの解析は比較的しやすそうです

よく考えてみれば、解析不可能なほどに難読化が行われると、今度はプログラムとして動作しなくなるので本末転倒になってしまうのでしょう。そのためProGuardによる難読化は、変換をしてもプログラムの動作に影響のない範囲で難読化が行われているようです。

注意点

まずはProGuardによる難読化はあくまで気休めレベルであるということを認識しなければなりません。私も実際にこうやって中身を確認するまでは、ProGuardを適用していればソースコードの盗用などは防げるものだとばかり思っていました。

またソースコードの書き換えが行われるため、以下の様なことに注意が必要です。

別途動作確認が必要

ProGuardはメソッド名やクラス名を書き換えてしまうため、プログラムによってはProGuardを適用することにより誤動作を起こす可能性があります

私はまだそのようなプログラムを作ったことはありませんが、クラス名やメソッド名を文字列等を使って参照するようなプログラムは動作しなくなるでしょう。そのため、ProGuardを適用したapkファイルを用いた動作確認を別途行う必要があります。これはちょっと面倒臭いですね・・・。

文字列リテラルの中身は変換されない

ProGuardは文字列リテラルの中身の変換は行いません。ここを変換すると、プログラム実行時に表示される内容や動作に影響が出てしまうからです。ここは逆に変換されないということに注意が必要です。

Read full post gblog_arrow_right

デザインを考える

ださいデザインからの脱却

1分間タイマーは、最初のバージョンでは文字とボタンだけが表示されている、非常にダサいアプリでした。それに比べると現在の見た目はだいぶましになったように思います。あくまで最初の頃よりはましになったなというだけで、カッコイイ見た目にするにはどうすればいいのかよく分かりません。

ただ、見た目をかっこ良くするという観点からのアプローチは難しくとも、使いやすくするという観点からのアプローチであれば、少し突破口が見えるような気がします。私がSmashing Android UI レスポンシブUIとデザインパターンという本を読んで、1分間タイマーに加えた変更を例にしてみましょう。

開始ボタンを押しやすくする

1分間タイマーを自分で使っていてとても不便だったのが、タイマーの開始ボタンが押しづらいことでした

1分間タイマーの当初のバージョンでは、デフォルトのButtonを開始ボタンとして利用していました。私はタイマーを開始させたらすぐに紙に向かって文字を書き出していきたいため、アプリの開始ボタンは横目で見ながら押すような感じで使っていました。しかし以前のバージョンの四角い小さなボタンでは、開始させたつもりが押せていないということがよくあってテンポが悪かったのです。

ボタンを大きくすれば使い勝手はかなり向上します。

新旧1分間タイマーの変化

残り時間の表示方法

ボタンの巨大化にともなって、残り秒数の表現方法も変えることにしました。開始ボタンを円形にしたので、その周りにバーのような感じで残り秒数が分かればスマートかなと考えました。

以前は単に文字で残り秒数を表示していました。しかし自分で使っていて、あと何秒残っているかを文字で読み取ることはいままで一度もありませんでした。そもそも音声による通知もあるので、残り秒数を文字で把握する必要性はありません。

円形のバーであれば視覚的に横目であとどれくらい残っているかが分かるので、文字で表示されるよりもマシだと思います。

ただ、このバーの動きがカクカクしているのが残念なところです。スムーズに動くように見せることができれば、見た目もよくなるのですが、実装方法が分かりませんでした。いずれやり方を調べて実装できたらいいなぁと思っています。

アプリ終了時の確認ダイアログをなくした

以前のバージョンでは、バックボタンを押した時に「終了しますか?」という確認ダイアログを表示していました。この終了するかどうか確認をとるアプリは、世の中にまだまだ多く存在しています。

みなさんは、アプリを使っていて終了時に確認ダイアログが出ることについてどう考えていますか?

「そんな確認はいらないんでさっさと終了しろよ」派でしょうか、「わざわざ確認してくれて親切やね、ありがとう」派でしょうか。

Smashing Android UI レスポンシブUIとデザインパターンでは、この終了時に確認ダイアログを出すのは、多くの場合開発者の都合によってつけられているものであると断じていました。

確認ダイアログは悪である

終了時に限らず、何らかの操作を行う際に確認ダイアログを表示するのは、取り返しの付かないことを実行する場合にユーザーに責任を転嫁させるため、開発者の都合で使われている悪しきものだとバッサリでした。

確認ダイアログを出したところでユーザーがちゃんと確認するかどうかは分かりません。操作ミスを恐れて確認ダイアログを表示させるという考え方もあるかもしれませんが、そのダイアログのボタンを操作ミスしないとは言い切れないはずです。

そこで確認ダイアログを使うくらいなら、操作を実行した後にそれを取り消すための手段をユーザーに提供することこそが、真のユーザーフレンドリーであるとこの本には書いてありました。ごもっともだと思いました。

終了時の確認で言えば、一度終了してしまうと起動するのに膨大な時間がかかってしまうため、操作ミスによる終了を防止する意味で出すというのはありかもしれません。起動するのに1分かかるゲームアプリで、やっと起動したと思った時に手が滑ってバックボタンを押してしまった。そういう場合であれば、確認ダイアログを表示する方が親切かもしれません。

ですが、その確認ダイアログは必要なのかと自問することが大切です。終了前の操作状態を復元することで対処できないか、いつ終了されてもデータが保存されるように作ればすむ話ではないか。そう考えることで使い勝手が向上していくのです。

Read full post gblog_arrow_right

Android Studio 0.8.10がリリースされています

Android Studio 0.8.10がCanary Channelでリリースされています。このアップデートにはバグフィクス以外に、新しい機能の実装が含まれています。

Memory Monitor

Memory Monitorが新たに実装されました。アプリのメモリ使用量をグラフでリアルタイムに確認することができます。なかなか便利です。

とりあえず使ってみましたが、カジュアルにメモリ使用量の確認ができるのは便利なのではないでしょうか。

ただ現状ではMemory Monitorのウィンドウサイズの変更がうまくできずに非常に邪魔臭い感じです。実用できるようになるのはもうちょっと先かなぁという感じです。

Memory Monitor実行例

Inspect Code

Analyze > Inspect Codeを実行することにより、コードチェックを行ってくれます。

Inspect Code実行例

String Bufferではなく、String Builder使えと指摘されました。その他にも詳しく教えてくれるみたいで、勉強のためのヒントがいっぱいですね。ありがたやありがたや。

外部ツールで変更を行った場合にダイアログで表示

Lintの変更を確認するのに、Android Studio 0.5.9で同じプロジェクトを開いたら、こんなウィンドウが出てきました。

外部ツールで変更を行った場合のダイアログ

こんな感じで、「なんかしらんけどファイル書き換わってんで? 再読込する?」と聞いてくれるようになったようです。(0.5.9で開いた後に「やっちまった」と思いましたが、この機能のおかげで助かりました)

その他いろいろアップデートあり

その他にも、Lintがパワーアップしていたり、ビルドエラーをハイパーリンクで修正できるようになったケースが追加されたり、バグ修正があったりと、いろんな機能が追加されたようです。

Lintについては、私はその存在を無視していたこともあって、以前と比較してどう変わっているのかよく分かりませんでした。ただ、今回改めて見てみると、いろいろと賢くなっているような気がします(黄色いメッセージがやたらと出てこなくなっている気がしましたが気のせいかもしれません)。

今回のアップデートはCanary Channelのみのようなので、先んじて試したい方はUpdate Channelを変更してみてください。

詳しくはリリースノートを参照してください。

データベースのデバッグ adb shellでDBの内容を確認する

アプリでデータベースを利用する場合、動作確認のためにその中身を確認したい時があります。

データベースへの書き込みを行ってみたものの、ちゃんと保存されているのか確認したい・・・よくあると思います。そんな場合に、adb shellを利用します。

adb shell

Androidアプリを開発するなら簡単なadbコマンドは知っておいたほうがいいと思います。ちなみにadb shellで端末やエミュレータにアクセスする手順は必ずしも以下のとおりでなくてもいいです。

まずはAndroid Studioからエミュレータを起動します。起動したらAndroid StudioのTerminalツールウィンドウを開きます。

Terminalツールウィンドウを開く

adb shellと入力すると、端末にログインできます。

データベースは特別な指定をしていない限り、/data/data/パッケージ名/databases/データベースファイル名に作成されています。

この例の場合は/data/data/jp.gcreate.sample.sampledatabase.app/databases/Sample.dbとなっています。

データベースファイルの場所

これがSQLiteのデータベースファイルになるので、ローカルにコピーしてツールを使って確認するなりしましょう。今回は中身を確認するだけなので、そのままターミナルからsqlite3コマンドを使ってみます。

sqlite3コマンド

sqlite3 データベースファイル名でSQLiteコマンドが実行されます。

sqlite3コマンド

このモードではSQLを使っていろいろできます。私が最初戸惑ったのはこんなかんじです。

  • 基本的に全てSQL文であると判断される
  • エンターでコマンドが実行されるわけではない
  • SQL文は最後に`;`つけない限り改行だと判断される
  • SQLiteのシステムコマンドを使いたい場合は最初にドットをつける

とりあえず以下のコマンドを知っていればなんとかなると思います。

  • `.help`コマンドでヘルプが見れます。
  • `.exit`コマンドで脱出できます。
  • `.schema`コマンドで、データベースファイル内のテーブル構造なんかが確認できます。
  • `.tables`コマンドで、データベースファイル内にどんなテーブルがあるか確認できます。
  • `SELECT * from テーブル名;`で、テーブル内のデータを確認できます。`

実際に実行してみると以下の様な感じで確認できます。

sqlite3コマンドでのデータベース内の確認

SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema
CREATE TABLE Sample(_id integer primary key autoincrement , InputText text not null , InputDate text not null );
CREATE TABLE android_metadata (locale TEXT);
sqlite> .tables
Sample            android_metadata
sqlite> SELECT * from Sample;
1|abc|2014/09/10 12:42:22
2|welcome to JAPAN!|2014/09/10 12:42:40
3|this is test|2014/09/10 12:42:50
4|aaa|2014/09/10 12:43:04
sqlite> 

私はドットインストールでSQLiteを勉強しました。AndroidのSQLiteは簡易版なので、使えないプロパティとかもあったりしますが、基本的なところはこれでなんとかなると思います。

Read full post gblog_arrow_right

@Overrideってなに?

Androidアプリを作成していてよく目にする「@Override」ですが、私はこれがなんなのかよく分かりませんでした。メソッドによってついていたりついていなかったりで、いまいち基準が分からなくて気持ち悪かったですが、あまり深く考えずにサンプルコードをコピペしていました。

Overrideってなに?

結論から言うと、この@Overrideはアノテーションの一種です。別に書かなくてもプログラムは動きます。

ではなぜ書いているのかというと、IDEやビルドツールに対して、「このメソッドはオーバーライドしたメソッドだぞ」と伝えるために書いているのです。

例えばAndroidでよく出てくるonStart()というメソッドをオーバーライドする際に、間違えてonStrat()と打ち間違えていたとします。仮に@Overrideのアノテーションをつけていなかったら、打ち間違えたメソッドでもエラーなくビルドできてしまいます。そしてアプリを実行すると・・・「想定通りに動かない。なんでだ!」となってしまいます。

プログラムを書いている本人は、メソッドをオーバーライドしているつもりで書いていても、それはIDEやビルドツールには分かりません。本人はonStart()をオーバーライドしているつもりでも、ビルドツールは独自のonStrat()メソッドだと解釈して処理してしまいます。@Overrideはそんなプログラマーの気持ちを彼らに伝え、しょうもないミスで時間を浪費しないようにするためのものなのです。

ちなみにアノテーションには、@Override以外にもいろんな種類があります。Java標準のアノテーションからはじまり、ライブラリ特有で利用するものもあります(Junit4で使う@Testなど)。ソースコードを簡略化するために使われたりもしています。

Android Studioを使いはじめの時に困ったこと

Android Studioを使い始めた頃、ものすごく困ったことがありました。(今も少し困ることはありますが・・・)

それは、書籍やWebでの情報はその多くがEclipse(ADT)の使用を前提にしているということです。特にAndroidアプリ開発を初めて間もない頃は、これが致命的なほどに効いてきます。

アプリをどうやって作っていくのかも分からない最初の頃は、どんなファイルをどういう手順で作っていくのかサッパリ分かりません。どこにどんなファイルがあって、アプリを動かすには何が必要なのか。書籍などに書いてある手順通りにやらないと、上手く動かなかった時に何が原因なのか自分で判断できません。

Android StudioとEclipseに大きな差異がなければ、本に書いてあることをそのまま読みかえれば済む話ですが、残念なことに両者はプロジェクトのディレクトリ構成が違います。使われている用語が同じ意味でないこともあります(プロジェクトとかモジュールの意味するところが違う)。対応している機能も異なります。知識が乏しいうちは、どこをどう読み替えればいいのかすら分かりません。

「この本に書いてあるこの手順は、Android Studioだとどうやればいいんだろう」とわからないことばかりでした。そのやり方をネットで調べようとしても、情報が少ないので解決策に辿り着けることは稀でした(最近は情報増えてきたのでそうでもないですが)。

手探りで似たような作業をしていると、最初は動いていたアプリが動かなくなったりしてよく困ったものです。アプリがなんかおかしくなったら、プロジェクトを1度削除して1から作りなおしたりしていました。

プログラミングしている時間より、明らかにAndroid Studioと格闘している時間が長く、勉強がさっぱり捗りませんでした。素直にEclipseを使うしかないのかと迷ったこともありましたが、Android Studioの便利な部分が捨てきれず、そのまま使い続けて今に至ります。

多言語に対応する

アプリ内で利用する文字列は、直接文字列を書き込む方法と、リソースファイルを参照する方法と2種類あります。基本的にはリソースファイルを参照する方法が推奨されます。

それはなぜかというと、主に多言語対応を簡単に行うためです。そのためにわざわざstrings.xmlへ文字列を書き出します。

Android Studio 0.8.8からTranslation Editorが追加され、この多言語対応が比較的簡単に行えるようになりました。といっても、まだ開発中の機能のため、操作性に難があります(執筆時利用バージョン0.8.9)。エクセルみたいな感じで編集できると便利なんだけどなぁ・・・と使っていて思いました。

具体的にはどうやっているか

ディレクトリ例

 └app
  ├res
   ├values ←デフォルトで利用されるリソース
   ├values-ja ←日本語環境で利用されるリソース
   ├values-en ←英語環境で利用されるリソース
   :

多言語対応ディレクトリ例

こんな感じでディレクトリを作成してそれぞれのリソースファイルを用意します。

日本語環境で利用していれば、values-jaに用意されているstrings.xmlの中身が使用されます。英語環境ならvalues-enのもの、それ以外の環境ならvaluesのものが適用されます。

多言語に対応できるのは何もstrings.xmlだけに限りません。文字を書き込んだ画像の多言語対応のために、drawableを同じように用意してやることもできます。

ソースコードから出力する文字列はどうするのか

ここは私の疑問なんですよね・・・。

とりあえずプログラムで端末のデフォルトロケールを取得して振り分ける処理をしてごまかしました。

if(Locale.getDefault().equals(Locale.JAPAN)){
    //日本語の場合の文字列
}else{
    //それ以外の場合の文字列
}

後から修正が大変になる駄目なパターンだと思いつつ、間に合わせで処理しました。

私がこうやって処理した部分は年月を表示する部分でした。例えば2014年9月と出力する部分です。日本語以外の環境で日本語が出てくるのはおかしいので振り分けてみました。

そもそもソースコードから直接文字列を出力するような実装が間違っているのかもしれません。一番いいのは20149とそれぞれ分割してViewで表示するようにしてやるのがいいのかもしれませんね。

ただそれだけでは対応できないところもあると思うので、ベストプラクティスが何なのか知りたいところです。