ServiceからActivityに値を投げたり画面を更新したりする方法

Android

ServiceからActivityに値を投げたり画面を更新したりする方法 サンプルソースコードあり

Androidで、バックグラウンドで動かしたり、長い時間がかかる処理をさせたり、待機させたりする動作はService(サービス)で動作させます。

たとえば、一時的に何かの情報が取得できないんだけど、何か情報が取得できたら、動かしているActivityの画面に表示したり、Activityの値を書き変えたい、ということはよくあると思います。

サービスは、Activityの裏で動いているので、一工夫しないとActivityを操作できません。
ちなみに、この方法はReceiver(レシーバー)でも使えます。

ここでは、一番簡単なサービスからActivytyに値を投げる方法を書いておきます。

以下、やり方です。

Handlerというものを使います。
Handlerが色々な値を、サービスやレシーバーからActivityに渡してくれます。

 /* Activity内 */
 
 public class MainActivity extends Activity {
 
 	private UpdateReceiver upReceiver;
 	private IntentFilter intentFilter;
 	private TextView message_tv;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.activity_main);
 
 		Context context = this;
 		Intent update_service = new Intent(context , UpdateService.class);
 		startService(update_service);
 		
 		upReceiver = new UpdateReceiver();
 		intentFilter = new IntentFilter();
 		intentFilter.addAction("UPDATE_ACTION");
 		registerReceiver(upReceiver, intentFilter);
 
 		upReceiver.registerHandler(updateHandler);
 		message_tv = (TextView)findViewById(R.id.message_tv);
 
 	}
 	
 	// サービスから値を受け取ったら動かしたい内容を書く
 	private Handler updateHandler = new Handler() {
 		@Override
 		public void handleMessage(Message msg) {
 
 			Bundle bundle = msg.getData();
 			String message = bundle.getString("message");
 
 			Log.d("Activityの名前", "はんどらーだよ" + message);
 			message_tv.setText(message);
 
 		}
 	};
 }
 /* Service内*/
 public class UpdateService extends Service {
 
 	private Handler handler;
 	private UpdateService context;
 
 	@Override
 	public int onStartCommand(Intent intent, int flags, int startid) {
 
 		super.onStartCommand(intent, flags, startid);
 
 		Log.d("UpdateService", "サービススタート");
 		sleep(4000);
 		
 		String message = "さーびすからのメッセージ";
 		sendBroadCast(message); 
 
 		return START_STICKY;
 	}
 
 	public void registerHandler(Handler UpdateHandler) {
 		handler = UpdateHandler;
 	}
 
 	@Override
 	public IBinder onBind(Intent arg0) {
 		// TODO Auto-generated method stub
 		return null;
 	}
 
 	public synchronized void sleep(long msec) {
 		try {
 			wait(msec);
 		} catch (InterruptedException e) {
 		}
 	}
 	
 	protected void sendBroadCast(String message) {
 
 		Intent broadcastIntent = new Intent();
 		broadcastIntent.putExtra("message", message);
 		broadcastIntent.setAction("UPDATE_ACTION");
 		getBaseContext().sendBroadcast(broadcastIntent);
 
 	}
 }
 /* Receiver内*/
  public class UpdateReceiver extends BroadcastReceiver {
 
 	public static Handler handler;
 
 	@Override
 	public void onReceive(Context context, Intent intent) {
 
 		Bundle bundle = intent.getExtras();
 		String message = bundle.getString("message");
 		
 		if(handler !=null){
 			Message msg = new Message();
 			
 			Bundle data = new Bundle();
 			data.putString("message", message);
 			msg.setData(data);
 			handler.sendMessage(msg);
 		}
 	}
 	
  	/**
  	 * メイン画面の表示を更新
 	 */
 	public void registerHandler(Handler locationUpdateHandler) {
 	    handler = locationUpdateHandler;
 	}
 
 }

AndroidManifest.xmlにサービスを書いておかないと、サービスが動きません。
エラーも出ないので、これは失敗しやすいポイントですね。

 /* AndroidManifest.xml内 <application>タグ内に記述 */
 <service android:name=".UpdateService"/> 

全部のサンプルコードはこちらで公開しています。
https://github.com/onlineco/serviceStudy/tree/0243c7ce917bc3f077e4fd54952f7fec22b6cb65 

  • 疑問点が1点あります。Service 内の registerHandler は必要なのでしょうか、実際に動かせばわかるのかもしれませんが、どこで呼ばれているのかわからず、 疑問に思った次第です。初歩的な質問で申し訳ありません。 — まにまに {2015-12-04 (金) 11:25:01}
  • まにまにさん、ずっと質問に気づかず申し訳ありません。Service 内の registerHandlerは、MainActivityのonCreate内にある、upReceiver.registerHandler(updateHandler);で呼んでいます。ここで紹介している方法だと、必要です。 — 中の人 {2016-02-02 (火) 13:21:12}
  • 横から失礼します。MainActivityのonCreate内にある、upReceiver.registerHandler(updateHandler);で呼んでるのは、UpdateReceiver の registerHandler ですよね?まにまに さんの質問は、UpdateService の registerHandler は必要ですか?とのことです。 — ひで太朗 {2016-06-19 (日) 19:20:56}
  • 横から失礼します。MainActivityのonCreate内にある、upReceiver.registerHandler(updateHandler);で呼んでるのは、UpdateReceiver の registerHandler ですよね?まにまに さんの質問は、UpdateService の registerHandler は必要ですか?とのことです。 — ひで太朗 {2016-06-21 (火) 21:41:04}
  • 横から失礼します。本文を読むと、サービスからActivityに値を投げる紹介とあります。これにはHandlerを使う方法があると紹介し、一例としてReceiver(レシーバー)でも使えます。と書かれています。さらに、ここでは、一番簡単なサービスからActivytyに値を投げる方法を書いておきます。とされているのに、コードの内容はレシーバーからActivityに値を渡す紹介コードとなっております。おそらくそれらがごっちゃになっているのかと思います。レシーバーと、サービスからのActivityへ値を渡す紹介ページを2つに分けたほうが分かりやすいかと思いますm..m以下、やり方です。Handlerというものを使います。Handlerが色々な値を、サービスやレシーバーからActivityに渡してくれます。 — {2016-07-06 (水) 11:23:03}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です