AndroidのIntentServiceからUIを継続的に更新する方法
IntentServiceとは
AndroidのIntentServiceは、バックグラウンド処理を非同期(ワーカースレッド)で実行するためのサービスコンポーネントです。ActivityなどからstartService()を呼び出しても、リクエストごとに新しいインスタンスが生成されることはなく、onHandleIntent()内の処理が完了するとサービスは自動的に停止します。必要に応じてstopSelf()を呼び出し、手動で停止させることも可能です。
本記事では、IntentServiceから送信されたデータを受け取り、UIを継続的に更新する方法をサンプルコードとともに解説します。
実装手順
ステップ1:新規プロジェクトの作成
Android Studioを起動し、メニューから「File」→「New Project」を選択して、必要な項目を入力し新しいプロジェクトを作成します。
ステップ2:レイアウトファイル(activity_main.xml)の編集
res/layout/activity_main.xmlに以下のコードを追加します。
<?xml version = "1.0" encoding = "utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android = "https://schemas.android.com/apk/res/android" xmlns:app = "https://schemas.android.com/apk/res-auto" xmlns:tools = "https://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity"> <TextView android:id = "@+id/text" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Start Service" android:textSize = "25sp" app:layout_constraintBottom_toBottomOf = "parent" app:layout_constraintLeft_toLeftOf = "parent" app:layout_constraintRight_toRightOf = "parent" app:layout_constraintTop_toTopOf = "parent" /> </android.support.constraint.ConstraintLayout>
このレイアウトではTextViewを1つ配置しています。IntentServiceからデータを受信すると、このTextViewの表示内容が随時更新されます。
ステップ3:MainActivity.javaの実装
src/MainActivity.javaに以下のコードを追加します。
package com.example.andy.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
TextView text;
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String someValue = intent.getStringExtra("someName");
text.setText(someValue);
}
};
@Override
protected void onStart() {
super.onStart();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.andy.myapplication");
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, intentFilter);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = findViewById(R.id.text);
final Handler handler = new Handler();
TimerTask timertask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
startService(new Intent(MainActivity.this, service.class));
}
});
}
};
Timer timer = new Timer();
timer.schedule(timertask, 0, 10000);
}
@Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
}
}このコードのポイントは以下の通りです。
- BroadcastReceiver:サービスから送信されたブロードキャストを受信し、TextViewのテキストを更新します。
- LocalBroadcastManager:アプリ内部だけで完結するブロードキャストを送受信できる仕組みです。他アプリに漏れないため安全です。
- Timer+Handler:10秒ごとにメインスレッド上でサービスを起動します。
- onStart()/onStop():画面の表示・非表示に合わせてレシーバーの登録と解除を行い、メモリリークを防ぎます。
ステップ4:service.java(IntentService)の作成
service.javaというクラスを作成し、以下のコードを追加します。
package com.example.andy.myapplication;
import android.app.IntentService;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
public class service extends IntentService {
public static volatile boolean shouldStop = false;
public service() {
super(service.class.getSimpleName());
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
protected void onHandleIntent(Intent intent) {
Intent intent1 = new Intent("com.example.andy.myapplication");
for(int i = 0; i < 10; i++) {
intent1.putExtra("someName", "Tutorialspoint.com "+i);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(shouldStop) {
stopSelf();
return;
}
}
}onHandleIntent()内では、1秒間隔で10回ループ処理を行い、そのたびにカウント値をExtraに格納してブロードキャストを送信しています。これにより、Activity側のTextViewがリアルタイムに更新されていきます。
ステップ5:manifest.xmlへのサービス宣言
manifest.xmlに以下のコードを追加します。
<?xml version = "1.0" encoding = "utf-8"?> <manifest xmlns:android = "https://schemas.android.com/apk/res/android" package = "com.example.andy.myapplication"> <uses-permission android:name = "android.permission.WAKE_LOCK"/> <application android:allowBackup = "true" android:icon = "@mipmap/ic_launcher" android:label = "@string/app_name" android:roundIcon = "@mipmap/ic_launcher_round" android:supportsRtl = "true" android:theme = "@style/AppTheme"> <activity android:name = ".MainActivity"> <intent-filter> <action android:name = "android.intent.action.MAIN" /> <category android:name = "android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name = ".service"/> </application> </manifest>
サービスをマニフェストに宣言することで、システムがサービスコンポーネントを認識できるようになります。
アプリの実行と結果確認
それではアプリを実行してみましょう。実機のAndroidスマートフォンをPCに接続しているものとします。Android Studioでプロジェクト内のアクティビティファイルを開き、ツールバーの「Run」アイコンをクリックします。接続したモバイルデバイスを選択すると、端末に以下のような画面が表示されます。


実行結果を見ると、IntentServiceから送信されたデータによって、UIが継続的に更新されていることが確認できます。
補足:最新のAndroid開発における注意点
なお、本記事で使用しているandroid.supportライブラリやIntentService自体は、現在では非推奨(Deprecated)となっています。最新のプロジェクトでは、AndroidXへの移行に加え、バックグラウンド処理にはWorkManagerやKotlin Coroutines(コルーチン)の利用が推奨されています。ただし、「サービス側の処理結果をブロードキャストで受け取り、UIに反映する」という本記事の基本的な設計思想は、現代の実装でもそのまま活かせる考え方です。
-
Androidアプリで端末起動時にサービスを自動開始する方法【コード例付きで解説】
はじめにAndroidアプリの中には、端末が再起動された後もバックグラウンド処理を継続したいケースがあります。本記事では、BroadcastReceiverとBOOT_COMPLETEDアクションを組み合わせて、端末の起動完了時にサービスを自動的に開始する方法を、実際のコード例とともにステップごとに解説します。この仕組みを実現するには、まずシステムから「起動完了」のブロードキャストを受け取るレシーバーを用意し、その中でActivityやServiceを起動します。以下の手順に従って実装していきましょう。Step 1:新規プロジェクトを作成するAndroid Studioを開き、「File」→「
-
Androidからマルウェアを削除する方法|感染の兆候と予防策を徹底解説
現代社会において、スマートフォンは生活に欠かせない存在となっています。銀行アプリ、ナビゲーションアプリ、各種ユーティリティアプリなど、個人の重要な情報や機能がほぼすべて詰まっています。だからこそ、プライバシーを守るためにも、スマートフォンをしっかりと保護することが何よりも重要です。パソコンと同様に、Androidスマートフォンもウイルス、トロイの木馬、スパイウェア、アドウェアなどの悪意あるプログラム(マルウェア)に感染する可能性があります。Androidマルウェアの主な目的は、機密情報の窃取、無関係な広告の表示によるユーザーの誤誘導、悪質なサイトへのリダイレクトなどです。マルウェアはさまざまな