[解決済み】AndroidサービスがActivityと通信する方法
質問
初めてAndroidアプリケーションを作成し、サービスとアクティビティ間の通信について理解しようとしています。バックグラウンドで動作し、GPSと時間ベースのロギングを行うサービスを持っています。サービスの開始と停止に使用されるアクティビティがあります。
そこでまず、アクティビティが開始されたときにサービスが実行されているかどうかを把握できるようにする必要があります。それについては、ここに他の質問があるので、私はそれを理解できると思います(しかし、自由にアドバイスを提供してください)。
私の本当の問題は、アクティビティが実行されていて、サービスが開始された場合、サービスがアクティビティにメッセージを送信する方法が必要なことです。現時点では単純な文字列と整数値で、主にステータスメッセージです。メッセージは定期的に発生するものではないので、他の方法があれば、サービスをポーリングするのは良い方法とは思えません。この通信は、Activityがユーザーによって開始されたときだけにしてほしいのです。つまり、Activityを開始し、Serviceが動作している場合、何か面白いことが起こるとActivity UIにステータスメッセージが表示されます。Activityを開始しない場合、これらのメッセージは表示されません(それほど面白いものではありません)。
サービスが稼働しているかどうかを判断し、稼働していればActivityをリスナーとして追加すればよさそうなものですが。そして、Activityが一時停止または停止したら、リスナーとしてのActivityを削除します。実際にそんなことができるのでしょうか?私が考える唯一の方法は、ActivityにParcelableを実装させ、AIDLファイルを作成して、Serviceのリモートインターフェースにそれを渡すことです。しかし、これはやりすぎだと思いますし、ActivityがどのようにwriteToParcel() / readFromParcel()を実装すればいいのか見当がつきません。
もっと簡単で良い方法はないでしょうか?助けてくれてありがとうございます。
EDITです。
後で興味を持った人のために、AIDLでこれを処理するためのGoogleのサンプルコードがsamplesディレクトリにあります。/apis/app/RemoteService.javaにあります。
解決するには?
サービスとのコミュニケーションには、3つの明白な方法があります。
- インテントの使用
- AIDLを使用する
- サービスオブジェクトそのものを使う(シングルトンとして)
あなたの場合、私なら3の選択肢を選びます。サービス自身への静的な参照を作成し、onCreate()でそれを入力します。
void onCreate(Intent i) {
sInstance = this;
}
静的関数を作る
MyService getInstance()
を返す、静的な
sInstance
.
次に
Activity.onCreate()
サービスを開始し、サービスが実際に開始されるまで非同期で待機し(アクティビティにインテントを送信することで、サービスが準備できたことをアプリに通知させることができます)、そのインスタンスを取得するのです。インスタンスを取得したら、サービスリスナーオブジェクトをサービスに登録すれば、設定完了です。注:アクティビティ内でViewを編集する場合は、UIスレッドで変更する必要があります。
Activity.runOnUiThread()
.
最後に、リスナーオブジェクトへの参照を削除する必要があります。
Activity.onPause()
そうしないと、アクティビティコンテキストのインスタンスがリークしてしまい、よくありません。
注意: この方法は、アプリケーション/アクティビティ/タスクがサービスにアクセスする唯一のプロセスである場合にのみ有効です。そうでない場合は、オプション 1 か 2 を使用しなければなりません。
関連
-
[解決済み】Android Studioです。「プロジェクトが C ドライブに作成されている場合、「タスク ':app:mergeDebugResources' の実行に失敗しました。
-
[解決済み] android.intent.action.MAINの意味は何ですか?
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] Androidでアクティビティ起動時にEditTextにフォーカスが当たらないようにする方法
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み] Androidアプリケーションのアクティビティ間でデータを受け渡すにはどうすればよいですか?
-
[解決済み] Androidのローテーションでアクティビティを再開する
-
[解決済み] Bitmapオブジェクトに画像を読み込む際にOutOfMemoryが発生する問題
-
[解決済み] グリッドレイアウトにおけるフリングジェスチャーの検出
-
[解決済み] Androidでサービスが稼働しているかどうかを確認する方法を教えてください。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】このアクティビティでは、Theme.AppCompatテーマ(またはその子孫)を使用する必要があります。
-
[解決済み】メソッド 'findViewById(int)' を解決できない。)
-
[解決済み】com.android.ide.common.process.ProcessException: aaptの実行に失敗しました! どうすればいいですか?
-
[解決済み] 設定 ':classpath' の依存関係をすべて解決できなかった。
-
[解決済み】Android Studio AVD - Emulator: 終了コード 1 でプロセスが終了
-
[解決済み】Android Studioでマニフェストのマージに失敗し、複数のエラーが発生した。
-
[解決済み】Android 8:クリアテキストのHTTPトラフィックが許可されない
-
[解決済み】android.content.res.Resources$NotFoundExceptionの取得:androidにリソースが存在する場合でも例外が発生する。
-
[解決済み] Xlint:deprecationを使用して再コンパイルする方法
-
[解決済み] Androidでイメージビューの背景を透明に設定する