SlideShare uma empresa Scribd logo
1 de 46
Baixar para ler offline
Real World
Android Akka
Taisuke Oe
自己紹介?
麻植泰輔 / TaisukeOe
GitHub: / Twitter:
お仕事
セプテーニ・オリジナル 技術アドバイザーとしてPullReqレビュー/新卒研修
座長
taisukeoe @OE_uia
BONX Android App
ScalaMatsuri
次回のScalaMatsuri
2018年3月予定!
現在日程調整中。お楽しみに!
今日話すこと
VoIPクライアント
VoIP : Voice Over Internet Protocol
VoIPサンプル
taisukeoe/VoIPAkka
Real World Example
BONXとは?
アウトドア用の通話システム
スノーボード
スキー
釣り
サイクリング
...
BONXアーキテクチャ
アプリ
VoIPクライアント
Android : Scala
iOS : Objective C / Swift
サーバー
APIサーバー : Ruby on Rails
Voiceサーバー : golang
Bluetoothヘッドセット
Android Akkaを使ったワケ
VoIPはステートフルな非同期ストリーム処理
Upstream
Recorder -> some DSP -> Encoder -> Socket
Downstream
Socket -> Decoder -> some DSP -> Player
DSP : Digital Signal Processing
全てのコンポーネントは状態が有り、更に スレッドセーフではない.
求められる障害からの回復力(Resiliency).
アウトドアでは、様々なエラーに遭遇する
不安定なネットワーク
圏外<->圏内間の度重なる移動
ハードウェアI/Oエラー
Bluetooth切断
アウトドアで遊んでいる最中は画面操作できないので、自動復旧が肝。
更に悪いことに:
エラーは必ずしも問題のコンポーネントで捕捉されない。
下流で気づくことがある
すなわちエラーを逆方向に伝搬させたい
問題のあるコンポーネントは、壊れた音声データを生むかもしれない
そしてノイズの原因になりうる
すなわちエラーの種類によっては、キューにたまった音声データを消さなければいけない
(逆もまた然り)
まとめ: BONXの要求仕様
ステートフルな非同期ストリーム処理
障害からの回復力
そこでAkkaの出番!
Akkaは 並行プログラミング、障害からの自動回復
... そして分散システムを構築するためのtoolkit.
(ステートフルな) 並行プログラミングのために
メッセージ駆動なアクターモデル
アクターは、状態を内部に閉じ込めたまま、並行プログラミングが容易
状態を内部に閉じ込めたActorの例
class PlayActor() extends Actor {
private val track: AudioTrack = createNewAudioTrack //state. Thread UN-safe
override def preStart(): Unit = track.play()
override def receive: Receive = {
//An actor retrieves and process a message from its mailbox one-at-a-time.
case AudioPacketMessage(content:ByteString) =>
track.write(content.toArray[Byte], 0, content.length)
}
override def postStop(): Unit = {
track.stop()
track.flush()
track.release()
}
}
Akkaによる障害からの回復力(Resiliency)
例外のハンドリング
Actorヒエラルキー
子アクターをsupervisorStrategyにもとづいてRestart, Stop, Resume
これによるRestartは メッセージボックスにメッセージを貯める.
モニタリング (Death watch)
監視対象のアクターがstopすると、監視側のアクターはTerminated(actorRef) メッセー
ジを受け取るので、そこで再生成する
これによるアクター再生性は メッセージボックス内のメッセージを破棄する.
アクターによる例外のハンドリングのサンプル
class ExceptionHandlingActor() extends Actor{
private var childActor:ActorRef = createChildActor
override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy(){
//Want to reset all mailboxes
case _:BrokenAudioDataException => Stop
//At default, child actors will be restarted with keeping their mailbox.
case t => super.supervisorStrategy.decider.applyOrElse(t, (_:Any) => Escalate)
}
def receive = {
//Stopped childActor will be recreated.
case Terminated(ref) => if(childActor == ref) {
context.unwatch(childActor)
childActor = createChildActor
}
}
private def createChildActor = {
val c = context.child(ChildActor.props)
context watch c
c
}
}
Recaps: なぜAkkaがうまく働いたのか
ステートフルな並行プログラミング
アクターの状態のカプセル化 / 一度に一つだけメッセージを処理するのでロック不要
障害からの回復力
アクターのヒエラルキーないしはモニタリングで管理
AkkaによってVoIP問題が「だいたい」解消した!
なぜ「だいたい」なのか ?
ものによっては例外として検知しにくい問題がある
オーディオドライバが場合によっては(ブロックしたまま)沈黙し、何も返さないことがある
銀の弾丸はない
Askパターンで、Ack が Timeout 内に返ってくるかチェック。
もし Ask がタイムアウトしたら、stopし再生成。
とはいえ、まずは「例外」として問題を検知する方法を探るべき
あまりオススメはしない
どうしてScalaがAndroidで使えるのか?
ビルドツールチェイン
scalac がScalaのソースをJava bytecodeにコンパイル
Android SDK の dex が Java bytecode を Dalvik Executable bytecodes に翻訳
Android標準のビルドシステムの主要機能は抑えている
sbt pluginと組み合わせ等が柔軟
scala-android/sbt-android
Android端末のスペックも上がってきた
ここ数年の agship級端末だと、最低でも:
4 to 10 cores CPU
3 to 4 GB memories
largeHeap=true で512MB程度使える
Q. じゃあScala Android使うべき?
万人にオススメはしない 
技術にはトレードオフがつきもの
Pros & Cons
Pros
豊富な言語機能とエコシステム ecosystem.
並行プログラミング
コレクションAPI
代数的データ型とパターンマッチ
トレイト
生産的
0.5 ~ 1.2 人で2年間新機能開発と運用まわしてました
サーバーサイドもScalaだと頭の切り替え不要で楽
他にScalaで嬉しい話
(View以外の)ステートレスな並行プログラミング
Viewの修正はUIThreadで行うため、Viewについては排他制御を考える必要性が薄い
Scalaの並行プログラミングAPIは優秀
Scala標準のFuture悪くないですよ.
UIThreadで実行するためのExecutionContextを定義して onComplete, andThen 等に明
示的に渡せる
UIExecutionContext Pattern
class UIExecutionContext(activity:Activity, reporter: Throwable => Unit)
extends ExecutionContext{
def execute(runnable: Runnable): Unit = activity.runOnUiThread(runnable)
def reportFailure(t: Throwable): Unit = reporter(t)
}
Future{
//some heavy calculation
}.onComplete{
case Success(result) => //reflect your result on views
case Failure(exp) => //show error message
}(uiExecutionContext) //Explicitly!
その他のScala Androidプロジェクトたち
セプテーニ・オリジナル
hits 6 million DLs!
47 Degrees
Akkaモジュール有り.
GANMA!
47deg/macroid
47deg/nine-cards-v2
47deg/scala-days-android
pocorall/scaloid
Cons
dexファイルあたり、メソッド数 64k の上限.
Scala標準ライブラリのjarはちょっと大きすぎる.
ProguardかMultiDexが必要.
Java8 supportなし
Android SDK toolchain はいまだ Java6+ 環境を対象.
Akkaのバージョンは2.3.16まで。ただしEnd-of-Lifeのマーク付き.
メモリ管理もある程度気にしたい
GoogleもLightbend公式サポート無し
Proguard
Proguardは使用されていないクラス、フィールド、メソッドを除くポストプロセシングツー
ル.
使用されていない とは 参照されていない.
Proguard はリフレクションを解しない.
AkkaはリフレクションをPropsや.confで多用している.
もしProguardが正しく設定されていなければ, NoClassDefFoundErrorないしは
NoSuchMethodErrorが ランタイムに投げられる.
Android Scalaをやる上でとても苦痛な作業.
とはいえ、Proguardの設定って最初から全部自分でやらなき
ゃいけないのか?
そんなことはない
Scala標準のライブラリ用のProguard設定は組み込み済
akka.actor と akka.io パッケージについては作りました
scala-android/sbt-android
proguard-con g.txt for akka-actor v2.3.16
新しいライブラリについて
Proguardの設定を簡単にやる方法(手抜き編)
実際とりあえず試すにはこれで十分
ライブラリが十分小さい限りにおいては.
例えば、Akkaについて同じ方法で設定するなら、proguard-con g.txtに以下の一行を足
す:
-keep class akka.** { *; }
後でちゃんと設定しましょう
メソッド数が64kを超えたタイミング.
MultiDexで乗り切るという手もある
アプリをリリースする直前にapkサイズを削りたいとき
Proguardの設定方法(推奨)
リフレクションで参照されているクラスを調べよう
grep -r "classOf" . が最も簡単
FQCN(フル修飾名)が.confファイルなどの設定ファイルに記述されているクラスを調べよ
う.
ラインタイムにNoClassDefFoundErrorや NoSuchMethodErrorを起こしたクラスを調べよう.
Proguard-Con gは最終的にこんな感じ:
# Akka configuration
# Akka 2.3.16
## for akka.actor
### Classes used in reference.conf
#### akka.actor.provider
-keep class akka.actor.LocalActorRefProvider { *; }
#### akka.actor.guardian-supervisor-strategy
-keep class akka.actor.DefaultSupervisorStrategy { *; }
#### akka.actor.mailbox
-keep class akka.dispatch.UnboundedMailbox { *; }
-keep class akka.dispatch.BoundedMailbox { *; }
-keep class akka.dispatch.UnboundedDequeBasedMailbox { *; }
-keep class akka.dispatch.BoundedDequeBasedMailbox { *; }
#### akka.actor.mailbox.requirements
-keep class akka.dispatch.BoundedDequeBasedMessageQueueSemantics { *; }
-keep class akka.dispatch.UnboundedMessageQueueSemantics { *; }
-keep class akka.dispatch.UnboundedDequeBasedMessageQueueSemantics { *; }
-keep class akka.dispatch.DequeBasedMessageQueueSemantics { *; }
-keep class akka.dispatch.MultipleConsumerSemantics { *; }
#### akka.scheduler.implementation
-keep class akka.actor.LightArrayRevolverScheduler { *; }
Proguardの設定でapkファイルのAPIメソッド数の比較
In akka.actor and akka.io 2.3.16 (and Scala 2.11.11)
Proguard setting # of methods in
dex
APK
size
Akkaの全クラスを残す 35033 1132KB
15784 590KBAkkaのクラスのうち、リフレクション、confファイルからの
参照のみ残す
注意: レポジトリで比較した結果で、もちろんどの程度Akka, Scalaのクラスを利用す
るかに寄って最終的な差は変わります
サンプル
AndroidはJava8をサポートするのか?
GoogleはAndroidのdex toolchainがJava8をサポートする旨アナウンスしている.
Java 8 Language Features Support Update - Android Developers Blog
とはいえ、Scalaと組み合わせてちゃんと動くのかはまだ分からない。
もしAndroidがJava8サポートしたら
Scala 2.12以上
Scala標準ライブラリjarが小さく。
Dotty(Scala 3.0)が 由来のcallgraph analysisによって、dead codeをなく
せるかも. (Proguardが不要に!)
Akka Streams (Akka 2.4)
ow graphの抽象化と, 扱いやすいback pressure管理。
Akka Typed (2.5)
Backo Supervisor (2.4以上)
Backo SupervisorとThreadLocalRandomをbackportすることもさほど難しくない
Dotty-Linker
メモリ管理
Android GCはConcurrent Mark & Sweep.
WrappedArray#mapやその他の高階関数はprimitive型をboxingすることがある
特にコピーが走りやすい場所ではring bu erが良い
ByteStringはconcatenationとslicingに効率が良い
狭いスコープでmutableなオブジェクト/コレクションを使うのは悪くない選択肢.
xuwei_k/nobox
結論
ActorモデルはAndroidでもうまく働く。特に ステートフル な並行プログラミングにおいて。
Akkaの障害からの復旧力は(アウトドアのような)エラーの起きやすい環境では役立つ
BONX AndroidアプリはAkkaの特長を活用してVoIPシステムを構築している.

Mais conteúdo relacionado

Mais procurados

Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Toshiaki Maki
 
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
cloudconductor
 
Webサーバの基礎知識【編集済み】
Webサーバの基礎知識【編集済み】Webサーバの基礎知識【編集済み】
Webサーバの基礎知識【編集済み】
Kikunaga Taishi
 

Mais procurados (20)

仕様をコードに落としこむ際気をつけたいこと
仕様をコードに落としこむ際気をつけたいこと仕様をコードに落としこむ際気をつけたいこと
仕様をコードに落としこむ際気をつけたいこと
 
Akkaの翻訳みんなでやろう Let's translate akka doc
Akkaの翻訳みんなでやろう Let's translate akka docAkkaの翻訳みんなでやろう Let's translate akka doc
Akkaの翻訳みんなでやろう Let's translate akka doc
 
AWSで開発するサーバレスAPIバックエンド
AWSで開発するサーバレスAPIバックエンドAWSで開発するサーバレスAPIバックエンド
AWSで開発するサーバレスAPIバックエンド
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
 
Java on Azure 2019
Java on Azure 2019Java on Azure 2019
Java on Azure 2019
 
AKS (k8s) Hands on Lab Contents
AKS (k8s) Hands on Lab ContentsAKS (k8s) Hands on Lab Contents
AKS (k8s) Hands on Lab Contents
 
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
 
Quarkus入門
Quarkus入門Quarkus入門
Quarkus入門
 
Ansible ネットワーク自動化チュートリアル (JANOG42)
Ansible ネットワーク自動化チュートリアル (JANOG42)Ansible ネットワーク自動化チュートリアル (JANOG42)
Ansible ネットワーク自動化チュートリアル (JANOG42)
 
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
 
Spring Framework ふりかえりと4.3新機能
Spring Framework ふりかえりと4.3新機能Spring Framework ふりかえりと4.3新機能
Spring Framework ふりかえりと4.3新機能
 
OpenStack APIを使った新しいアプリケーションモデル
OpenStack APIを使った新しいアプリケーションモデルOpenStack APIを使った新しいアプリケーションモデル
OpenStack APIを使った新しいアプリケーションモデル
 
Webサーバの基礎知識【編集済み】
Webサーバの基礎知識【編集済み】Webサーバの基礎知識【編集済み】
Webサーバの基礎知識【編集済み】
 
How to contribute AWX
How to contribute AWXHow to contribute AWX
How to contribute AWX
 
Akka meetup 2014_sep
Akka meetup 2014_sepAkka meetup 2014_sep
Akka meetup 2014_sep
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
 
ログについて改めて考えてみた
ログについて改めて考えてみたログについて改めて考えてみた
ログについて改めて考えてみた
 
Akka入門
Akka入門Akka入門
Akka入門
 
Jjug CCC 2019 Fall Azure Spring Cloud
Jjug CCC 2019 Fall Azure Spring CloudJjug CCC 2019 Fall Azure Spring Cloud
Jjug CCC 2019 Fall Azure Spring Cloud
 
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarconSeasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
 

Semelhante a Real World Android Akka - 日本語版

ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
Akira Inoue
 

Semelhante a Real World Android Akka - 日本語版 (20)

Azureをフル活用したサーバーレスの潮流について
Azureをフル活用したサーバーレスの潮流についてAzureをフル活用したサーバーレスの潮流について
Azureをフル活用したサーバーレスの潮流について
 
仮想通貨取引所 bitbank の IaC の導入と実践
仮想通貨取引所 bitbank の IaC の導入と実践 仮想通貨取引所 bitbank の IaC の導入と実践
仮想通貨取引所 bitbank の IaC の導入と実践
 
VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発
 
AWSによるサーバーレスアーキテクチャ
AWSによるサーバーレスアーキテクチャAWSによるサーバーレスアーキテクチャ
AWSによるサーバーレスアーキテクチャ
 
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
 
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
 
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
 
Unity開発ロードマップ最新情報
Unity開発ロードマップ最新情報Unity開発ロードマップ最新情報
Unity開発ロードマップ最新情報
 
Smart Tennis Lesson Serverless Design
Smart Tennis Lesson Serverless DesignSmart Tennis Lesson Serverless Design
Smart Tennis Lesson Serverless Design
 
シスコ装置を使い倒す!組込み機能による可視化からセキュリティ強化
シスコ装置を使い倒す!組込み機能による可視化からセキュリティ強化シスコ装置を使い倒す!組込み機能による可視化からセキュリティ強化
シスコ装置を使い倒す!組込み機能による可視化からセキュリティ強化
 
GTC Japan 2016 Rescaleセッション資料「クラウドHPC ではじめるDeep Learning」- Oct/5/2016 at GTC ...
GTC Japan 2016 Rescaleセッション資料「クラウドHPC ではじめるDeep Learning」- Oct/5/2016 at GTC ...GTC Japan 2016 Rescaleセッション資料「クラウドHPC ではじめるDeep Learning」- Oct/5/2016 at GTC ...
GTC Japan 2016 Rescaleセッション資料「クラウドHPC ではじめるDeep Learning」- Oct/5/2016 at GTC ...
 
Web socketドロンくん その後-
Web socketドロンくん その後-Web socketドロンくん その後-
Web socketドロンくん その後-
 
Open Source x AI
Open Source x AIOpen Source x AI
Open Source x AI
 
Osc fukuoka xAI Meetup
Osc fukuoka xAI MeetupOsc fukuoka xAI Meetup
Osc fukuoka xAI Meetup
 
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
.NET の今と未来 ~ デバイス&クラウド ネイティブを目指して
 
デモで楽しむ Visual Studio 2022 & .NET 6 最新アップデート
デモで楽しむ Visual Studio 2022 & .NET 6 最新アップデートデモで楽しむ Visual Studio 2022 & .NET 6 最新アップデート
デモで楽しむ Visual Studio 2022 & .NET 6 最新アップデート
 
サーバーレスの今とこれから
サーバーレスの今とこれからサーバーレスの今とこれから
サーバーレスの今とこれから
 
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
[AC11] サーバー管理よ、サヨウナラ。サーバーレスアーキテクチャの意義と実践
 
Microsoft AI セミナー - Microsoft AI Platform
Microsoft AI セミナー - Microsoft AI PlatformMicrosoft AI セミナー - Microsoft AI Platform
Microsoft AI セミナー - Microsoft AI Platform
 
Using Windows Azure
Using Windows AzureUsing Windows Azure
Using Windows Azure
 

Mais de Taisuke Oe

How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
Taisuke Oe
 

Mais de Taisuke Oe (10)

プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
 
Monix Taskが便利だという話
Monix Taskが便利だという話Monix Taskが便利だという話
Monix Taskが便利だという話
 
How to get along with implicits
How to get along with implicits How to get along with implicits
How to get along with implicits
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
 
AuxパターンをDottyで解決する
AuxパターンをDottyで解決するAuxパターンをDottyで解決する
AuxパターンをDottyで解決する
 
Real World Android Akka
Real World Android AkkaReal World Android Akka
Real World Android Akka
 
多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン
 
Android BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsAndroid BLEのつらみを予防するTips
Android BLEのつらみを予防するTips
 
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
 

Real World Android Akka - 日本語版