Android 非同期処理についてまとめてみた


Androidには、UIに影響を与えないよういくつか非同期処理が用意されています。
今回は非同期処理の代表的な

・Service
・IntentService
・HandlerThread

について違いを踏まえながらまとめます!
非同期処理について(http://codezine.jp/article/detail/9746)

まずはServiceとIntentServiceについて説明します。

■ Service
・メリット
– Activityに依存せずに長時間のバックグラウンド処理に向いている。
– Contextを持っている。

・デメリット
– メインスレッド上(UIスレッド上)で動作するため、重い処理を行うと画面のレスポンスが遅くなったり、アプリが落ちる。

※Serviceの優位性
ServiceはActivityと同一のスレッドで動いているため、
Serviceを使わずにActivityからスレッドを生成すればいいのでは?と思った方がいるのではないでしょうか?
重要なのはServiceはContext(アプリの状態)を保持していることです。
Activityからでもスレッドは生成し処理を行うことは可能ですが、Activityが終了してしまうと、Activityに関連したContext(アプリの状態を保持した情報)は使用できなくなります。
そのため、Contextを利用したバックグラウンド処理にはServiceを使う必要があります。

■ IntentService
・メリット
– Activityに依存せず非同期の処理に向いている。
– 内部にHandlerThreadを持っているため、メインスレッドとは別のスレッド上で逐次処理を行う。

ServiceとIntentServiceの違いを見てみる

下記にServiceを使った処理とIntentServiceを使った処理を記載します。
ActivityからIntentを使ってService/IntentServiceを呼び出します。
・Activity

・Service(あえてfor文を使い重い処理を行う)

→アプリが落ちる。

・IntentService(あえてfor文を使い重い処理を行う)

→UIに影響を与えないため、アプリは落ちない。

次にHandlerとHandlerThreadについて説明します。

HandlerThreadについて

HandlerThreadは内部にLooperを持ち、Handlerによって送られてきたメッセージを逐次処理するための仕組みです。わからない用語が出てきたので、まずは”Looper”と”Handler”について説明します。

LooperとHandlerについて

Looperとは

Looperとは内部にMessageキューを持ち、順番にキューから取り出したメッセージを処理する仕組みです。
これはAndroidの基本的な仕組みとなっておりActivityやServiceなどもこのLooper上で動作しています(デバックしてみるとわかります。はい)。
そしてこのActivityやServiceは特別なメインルーパー(メインスレッド)で動作しており、画面に関するウィジェットの変更はメインルーパーで行わなければなりません。
※別スレで行うとエラーが出ます。

Handlerとは

HandlerとはそのLooperにMessage(タスク)を届けるためのメッセンジャーです。

HandlerとHandlerThreadの違いを見てみる

Handlerはメインスレッド上で行われています。
HandlerThreadは新たにThreadを生成して、そこで処理を行います。

→デバックして変数sの中身を確認する。
s = main
メインスレッド上の処理のため、重たい処理を記載するとアプリは落ちる。

→デバックして変数sの中身を確認する。
s = other
別スレッドを生成しているため、重たい処理を記載してもUIに影響を与えることはなくアプリが落ちる心配はない。
なるほどなるほど、ここで疑問。
Q 画面に関する操作はメインスレッド上で行わなければならないとのこと。もし、別スレッド上で行ったらどうなるのだろうか?

・結果
問題なく、ボタンが読み込まれました。
Handlerの引数(メインスレッドのLooper)にHandlerThreadのLooper処理の結果を渡してるから、
別スレッドの処理結果をメインスレッドに渡しているからなんだ。

(http://ichitcltk.hustle.ne.jp/gudon2/index.php?
pageType=file&id=Android010_Handler)
手順

1.別スレッド(HandlerThread)を生成
2.別スレッド開始
3.HandlerThreadインスタンス から Looperインスタンス 取得
4.Handlerインスタンスを生成(3で取得した Looperインスタンス を 引数指定)
5.4 で作成した Handlerインスタンス を使用(Handler#post 等)

参考
http://daichan4649.hatenablog.jp/entry/20111004/1317724067
https://realm.io/jp/news/android-thread-looper-handler/

UIスレッドからのみ画面操作が可能
http://dev.classmethod.jp/etc/22853/


DACエンジニア採用情報

  関連記事

Scala入門 基礎編「Scalaの書き方を理解しよう」 – PHP使いからScala使いへ転身!

はじめに みなさんこんにちは、プロダクト開発本部の亀梨です。 普段はXmediaOneというメディアプランニング・広告運用管理・トラッキング・マーケティング分析を行う 統合プラットフォームの開発を担当しています。 さて、今回はScala入門第二弾として、Scalaの書き方を紹介する基礎編をお送りしま …

読み方がわからない技術用語 2015

英語圏での読み方を基本的には参考にしています。英語圏でも複数の読み方をしているケースもあるようなので、あくまでも参考程度。2015と書きながら、古い言葉も混じってますが。 async – えーしんく Alt – おると ASUS – えいすーす bower &#8 …

SDKってどうやって作ってるの?【Android編】

こんにちは。4度目の投稿です。 現在私はAndroidのSDKを開発しています。 javaにもAndroidにもSDKにも手を出したのは初めてなので、最初はそもそもSDKのイメージが湧かず、ふわふわした状態で始めました。 SDKと調べても「あるソフトウェアを開発するために必要なプログラムや文書などを …

kubernetes の全ノード上で同じコンテナを動かす

今回は、kubernetes上で同一コンテナを全ノードで動かす方法を紹介したいと思います。kubernetes自体の起動方法はここでは割愛します。 はじめに 以前、CoreOSのFleet上でmackerel-agentを動かすということを行いました。今回は、kubernetes上で同じようにクラス …

自社サービスのDocker化(前編)

こんにちは。 インフラ開発部の上田です。 普段は自社開発システムのインフラ担当として、日々頑張って仕事をしています。 今回は、近年話題になっているDockerについて、取り上げてみようと思います! なぜDockerなのか・・・? そもそもDockerとは何か・・・?   当社では様々なサー …

初心者がRailsで開発 – deviseでユーザー認証設定 –

こんにちは、2年目のYukaです。 開発部所属でありながら実は、、 実際に自分で手を動かして開発する機会がなかなかありませんでした。。 しかしついに、、、 開発初心者がRailsでWebアプリの開発に挑戦します!! 今回のゴールは社内でも使用しているGoogleアカウントで簡単にログインができるよう …

D3.jsとその活用事例について

D3.jsとは? D3とは「Data Driven Document」の略で、データに基づいてドキュメントを操作するための JavaScript ライブラリです。 ご存知の方も多いと思いますが、ちょっとだけD3.jsの基本的な使い方、そして弊社プラットフォームでの利用についてご紹介したいと思います。 …

Railsたった14行でアドサーバーAPIができた話

こんにちは。駆け出しエンジニアの近江です。 最近Railsにハマっているので、私が2年間担当しているアドサーバの、簡易版をRailsで作ってみました。 広告やキャンペーンを登録する管理画面はある前提で、ここからたった14行追加するだけでアドサーバーのHTTP APIを作りたいと思います。ついでに配信 …

【未経験からのRuby on Rails – 第2回】Rubyのプログラムを書いてみる(Mac)

こんにちは。新卒1年目のmatsuariです。 前回はRubyとは何か、簡単にご紹介をしましたが、 今回は実際にRubyファイルを作成して、プログラムを書いてみるところまでご紹介していけたらと思います。 Mac環境のプログラミング初心者向けです。 はじめに、Rubyのプログラムを書くためのファイルを …

Vagrantの機能を使って開発環境の効率をあげてみた。

プラットフォーム・ワンのシステムの運用・保守担当のエンジニアです。 保守の仕事に関わると、 ユーザからのお問い合わせだったり、監視アラートによる検知から システムを調査することがあります。 ログとソースコードを見て、不具合を特定し改修する。 すぐできればカッコいいですが、 「本番環境に反映して別のエ …