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}