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}