19. 状態を内部に閉じ込めた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()
}
}
21. アクターによる例外のハンドリングのサンプル
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
}
}
32. 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!