60
Android ウェブアプリケーション 連携術 株式会社はてな

Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

Androidウェブアプリケーション

連携術

株式会社はてな

Page 2: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

自己紹介

Page 3: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

株式会社はてな

アプリケーションエンジニア

id:cho45

Page 4: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

について

Page 5: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

● ウェブサービスの開発・運営をしている会社です

● 京都・東京

● Perl を使うことが多いです

(もちろん他の言語も使います)

Page 6: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード
Page 7: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード
Page 8: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

cho45について

Page 9: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

株式会社はてな

京都8F(@hatena8f)勤務

Page 10: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

cho45

http://www.lowreal.net/

京都・サービス開発部・アプリケーションエンジニア

普段は Perl / JavaScript をメインにほか色々

領域:

● アプリケーションサーバコード

● ユーザーインターフェイスコード

Android 開発はじめてから Java を触る

Page 11: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

趣味

Page 12: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

神社巡り

Page 13: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

本題

Page 14: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

Agenda - Android ウェブアプリケーション連携術

はてなで開発された

Android アプリケーションの

事例を通して実際の開発方

法についてご紹介致しま

す。

Page 15: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

Agenda - Android ウェブアプリケーション連携術

1. 事例1: フォトライフ for Android

ウェブではできないこと、Android で生まれた可能性

メモリ管理

2. 事例2: はてなログイン管理

なぜこのアプリケーションが必要だったか?

Android のパーミッション管理

3. 事例3: はてなモノリス

ウェブアプリケーションとの密な連携

設計の際気をつけたこと

4. 事例4: はてなココ

Page 16: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

http://f.hatena.ne.jp/guide/android

Page 17: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード
Page 18: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなフォトライフ for Android

最初に取り組んだ Android アプリケーション

ウェブでは解決できないことを解決する

● はてなフォトライフの写真を快適に閲覧

● 写真アップロード・自動アップロード

● スライドショー

● など

Page 19: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

写真閲覧

Activity Stack を活用した実装に

一覧系は同一 Activity 

インテントを投げて全部別インスタンス

→ おかげで実装はそこそこ綺麗

ウェブページと 1:1 になる実装 (Activity == Page)

が、問題点が……

Page 20: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

写真閲覧

Stack に残っている Activity インスタンスは開放されない

Android OS は・ユーザが操作している Activity

が属する

・アプリケーション

を自動で kill しない (古すぎる Activity は開放される)。

メモリを大量に使う Activity を短時間に積むと OOM    

Page 21: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

写真閲覧

Stack に残っている Activity インスタンスは開放されない

サムネイルを大量に保持すると当然 OOM

ページを辿りすぎると落ちる事態に……

→遷移前に保持しているサムネイルは開放し、

onResume 時に更めてキャッシュから読み直す実装へ

→Back ボタン時に若干ロードが走るようになったが許容範囲

あまりメモリを食わない情報は onLowMemory で開放

Page 22: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

写真閲覧

端末回転の実装

普段回転をオフにして開発していたため暫く気付かず

回転したら全て作りなおす実装では重すぎた

→回転時に発生する onRetainNonConfigurationInstance

を真面目に実装して解消

読みこんだ画像を保持して持ちこすようにしただけ

Page 23: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

写真閲覧実装時の教訓

メモリ開放は繊細に実装しよう

端末回転はマジメに実装しよう

Page 24: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

写真アップロード

Service を使わなくても実装できるかと思ったが無理だった

→ 普通に Service を使って実装

(Service == Worker サーバ的なもの)

プログレスの Notification などに苦労したが

基本に忠実に実装

写真閲覧のプロセスと別にすることで 

Service 自体のメモリ使用量を減らし、kill されにくくしている

Page 25: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

外部 Intent からのアップロードに対応

● 非同期API (Intent.ACTION_SEND)

Service に投げっぱなし

● 同期API (独自Intent)

プログレスを表示するため aidl を書き、

内部でIPC

写真アップロード

Page 26: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

● 撮った写真を自動アップロード

● フォトライフ側の twitter 連携を使うと

自動で twitter 投稿までやってくれる

寒くてアップロード待ってられないし、全部 twitter に投稿してライブ

したいし…… というとき非常に便利

写真自動アップロード

Page 27: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

● Service を常時起動

● 数十秒ごとにファイルシステムを監視

カメラの撮影Intentを掴まえたほうがいいのだが

各社カメラアプリがそれを発行するか解らかったため

確実に動く方法を採用

● 工夫

・スクリーンがついているときだけ監視

・lastModified が起動直後狂うので頑張る

写真自動アップロード

Page 28: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

基本的に Service は死なないことになっているが

何らかの原因で死なれて復帰しないと困るので

AlarmManager で定期的に死活を確認している

Notification が出ていても、起動しているとは限らない

Service の常時起動

Page 29: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

少なくとも HT-03A (1.6) で再現して困った。

以下で解決

long lastModified = file.lastModified() - TimeZone.getDefault().getRawOffset();

起動直後はTZが設定されるまでディレイがある……

起動直後しか発生しないのでデバッグが▽めんど

(Tips) 起動直後の時間狂い

Page 30: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

アップロード実装時の教訓

サービスは利用すべきなら積極的に

プロセスをうまくわけよう

Page 31: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

メモリ消費削減の手

うまくツールを使おう

● Memory Analyzer (Eclipse plugin) 参考

どんなオブジェクトがメモリ消費しているかわかる

(画像じゃない部分で消費量が多い部分があってなおした)

● DDMS で見れるスレッド一覧 (エミュレータ)

意図していないスレッドができていないか?

(HttpClient がスレッドを作るので一本化した)● traceview ...

プロファイル結果をグラフィカルに見れるやつ

SDK に入ってる Debug.startMethodTracing

Page 32: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

バグレポート送信機能

2系のOSだとマーケットでバグレポが見

れますが、

1.6系だと見れない or マーケットにあげ

てないと見れない

組込みが簡単なよう、メールで送るような

やつを書いて使っています。

http://subtech.g.hatena.ne.jp/cho45/20100210/1265797885

Page 33: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

バグレポート送信機能

欲しいけど(端末供給的に)買えない

端末から送られてくるとmoge感

Page 34: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなログイン管理

Page 35: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなログイン管理

アカウント情報管理アプリ

● ユーザ情報を何回も入れたくない

(Android 2系にはOS組み込みで同様のものがあるが、1.6 にはなかったので、仕方なく)

Page 36: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなログイン管理

最初はOSの Content Provider + permission を

考えていた

→セキュリティ上の問題で止め、

Intent のやりとりに変更

Page 37: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

<permission>

<permission> は先に定義したもの勝ちする

→プリインストールアプリケーション以外は

安全性を確保できない

検証

Page 38: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなログイン管理

Android 2系に対応とともに

補助アプリケーション扱いにしたい

OS組み込みのアカウントマネージャは

まだ検証中

Page 39: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなモノリス

http://mono.hatena.ne.jp/バーコードを読んでモノを共有するサービス

アプリは Android, iPhone で提供

アプリでバーコードを読んで投稿する

● 外部ライブラリ組込み

● ウェブとの連携

Page 40: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

設計と実装

最小工数でリリースすること

● できる限りはウェブで

(我々のメインフィールドはウェブなので)

● ウェブのシームレスな連携

(Android は OS 自体がそうなっており、理にかなっている)

Page 41: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

外部ライブラリ

zxing を使用

既存のものを最大限利用したいが……

● リソースファイルが……

● クラスの依存関係が……

ライブラリ系は単にコピーするだけにしたいが

変更なしでは無理だったので、

頑張って移植作業をした

Page 42: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

リソース名・リソースファイル

別のプロジェクトのを利用しようとすると

名前がかぶって困る

ログイン管理統合版フォトライフでも同様の問題が発生したが、こちらはかぶらないように両方を調整することで対処

res/values/strings.xmlres/values/accounts_strings.xml@ -> ../../modules/HatenaAccounts/res/values/accounts_strings.xml

Page 43: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

ウェブとの連携

● 本番サーバとテストサーバがある

● 別々のバイナリを作るのは面倒

社内の人に試してもらうときも面倒→非表示な設定項目を作ることで対応

特定の Intent を手動で投げることで表示

adb shell am start -n com.example.foo/.Setting --ez debug true

Page 44: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

adb shell am start -n com.example.foo/.Setting --ez debug true

で開発者用の設定が

出るように

設定でドメイン切り替え

デバッグサーバ

Page 45: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

onCreate でif (!intent.getBooleanExtra("debug", false)) { pAdvancedContainer.removePreference( findPreference("test_server_enabled_key") );}

とかやって消しているだけ

デバッグ用

Page 46: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

● はてなでは翻訳者とやりとりするツールがある

● ID + 言語 + 単数複数活用 のデータベース

国際化

Page 47: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

● 翻訳データベースから strings.xml は自動生成

● OS組込みのリソース切替えだと不完全

● 複数・単数対応は独自に Locale.java

(リフレクションで頑張っている)

国際化

Page 48: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

<string name='monolith_users'>%1$s users</string><string name='monolith_users_1'>%1$s user</string><string name='monolith_users_qt'>1_o</string>

Locale.getStringN(this, R.string.foo, n);

none : 複数形"_1" : 単数形"_qt": 単数形ルール

● 1 だけ単数形 (1_o) (英語など)● 0 と 1 が単数形 (01_o) ()● 単複同形 (o) (日本語など)

国際化

Page 49: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなココ

http://c.hatena.ne.jp/イマココ(位置情報)共有サービス

アプリは Android, iPhone で提供

Page 50: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

WebView の組み込み

● ココアプリでは WebView がアプリ組込み

● 開発者独りでバックエンドからアプリまで作ってい

るので、インターフェイスを Web によせ、最小限

実装

● リソースを多く使うなど欠点はあるが、必要な部分

から徐々に置き換えたりができる

Page 51: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

WebView の組み込み (BK)

● API が JSON の中に HTML をそのまま返す 

→ WebView に流しこみ

というが部分的にある

● なぜか <meta charset="utf-8"/> がないと

文字化け

Page 52: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

WebView の組み込み

● http 経由で読み込んでいる部分

● アプリかどうかで一部(サーバサイドで)

出しわけし、最小限の転送になるように

Page 53: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

ウェブエンジニアの視点から

Android に対して思うこと

Page 54: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

Android になってアプリが作れても

基本はウェブ

Page 55: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

Intent は高級になったハイパーリンク

Activity は進化したウェブページ

Page 56: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

Service はワーカープロセス

Content Provider はデータベース

Page 57: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

ウェブとのシームレスな連携は

(早すぎるかもしれないが) 恐しく未来的

Page 58: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

うまく生かして開発していきたい

Page 59: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

はてなの開発リソースhttp://developer.hatena.ne.jp/

利用可能な Intent の仕様も纏まっています

是非使ってください!!!

Page 60: Android ウェブアプリケーション 連携術 · 2011-12-01 · 同期API (独自Intent) プログレスを表示するため aidl を書き、 内部でIPC 写真アップロード

ご清聴ありがとうございました。

Androidウェブアプリケーション連携術

株式会社はてな

アプリケーションエンジニアcho45