![]() |
AndroidのServiceについて |
2015/04/25 23:50:32 |
![]() |
||
Noranekoです。
『これから英語は必要だ!』とか、
『これからは国際社会、海外に目を向けろ!』とか言う人に限って、
海外滞在とか全くなくて、パスポートすら持ってないのが現実だょ^ω^
でファストフードマスターの私に言わせれば、
IN-N-OUTしか認めません!
今秋に『Carl's Jr.』も来るみたいだけど、また行列するんだろうな・・・
でもCarl's Jr.はメニューが多くて、LAで滞在してた近くにあったので、
しょっちゅう行ってました^ω^

一応タバコと比較してます。
ということで、アメリカのファストフードとかのお話はまた今度にしましょう。
前回のお話の続きになります。
バックグラウンドで常駐させたい
↓
いつのまにか死んでる
↓
Serviceにすればいいよ!
と、ここまで理解してて、その後サンプルソースから大改造してみました。
できました。
重要なところをまとめてみます。
①Activity等からServiceを起動させる為にAIDLを作成する。
②Serviceからの戻り値をBroadcastReceiverで取得する。
③BroadcastReceiverからさらにActivityへ値を戻す。
①について、前回ほんのり書いてますが、
ActivityからServiceを独立させて呼び出す為に、AIDLファイルという物を作って
そこからServiceを呼びます。
下準備として、
public class MainService extends Service{ }MainService.java
interface IService { }IService.aidl
AndroidManifest.xml
自分の目的では、Activityが死んでもServiceを継続させたい為、
『onStartCommand』を使います。
直接使えないので、下記のようにします。
public class Hoge extends Activity{ public void test(){ // Serviceを実行 Intent intent = new Intent(IService.class.getName()); startService(intent); } }
もう一つのやり方は、
『ServiceConnection』を用いて、『bindService』を使うやり方です。
public class Hoge extends Activity{ private IService service = null; private ServiceConnection con = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mService = IService.Stub.asInterface(service); } public void onServiceDisconnected(ComponentName className) { } }; public void test(){ // サービス実行 Intent intent = new Intent(IService.class.getName()); // バインド bindService(intent, con, Service.BIND_AUTO_CREATE); }
後者は、Activityが死ぬとServiceも死んでしまいます。
ただ、サービスのいろいろなメソッドにアクセスできるので、
前者とは異なる使い方が可能です。
多分ここまでで???の方も多いと思いますが、
実行したいサービス(MainService.java)
と
実行したいサービスを起動するためのインターフェイス(IService.aidl)
があって、Activityから2パターンの呼び出しが可能で、
呼び出し方によりできることとできないことに分かれます。
うむ。
これは難しい。
とりあえず先に進もう。
②について、これは①の後者を選択してバインドした人には
あまり意味がないのかもしれません。
public class MainReceiver extends BroadcastReceiver{ }MainReceiver.java
AndroidManifest.xml
例によってこれを前提とします。
先程の①の前者を
public class Hoge extends Activity{ private MainReceiver receiver = null; public void test(){ // Serviceを実行 Intent intent = new Intent(IService.class.getName()); startService(intent); // レシーバ―登録 IntentFilter filter = new IntentFilter("hoge"); receiver = new MainReceiver(); registerReceiver(receiver, filter); } }
これだけです。
次に、MainServiceの何かを返すメソッドに
public void payBack(){ Intent intent = new Intent("hoge"); intent.putExtra("test", "test"); intent.putExtra("suji", 99); sendBroadcast(intent); }
最後にMainReceiverに
public class MainReceiver extends BroadcastReceiver{ public void onReceive(Context context, Intent intent){ // 値を取得 String s = intent.getStringExtra("test") int i = intent.getIntExtra("suji", 0) System.out.println("this is broadcast @" + s + "@" + String.valueOf(i)); } }
比較的わかりやすいですね。
③ここで悩みました。みんな②でToastで表示して終了が多いです!
ではなくて、私みたいにActivityに返したい人の方が多いはずです!
で、どっかのブログがひっかかり、無事、事なきを得ました。
先程のMainReceiverを改造します。
public class MainReceiver extends BroadcastReceiver{ public void onReceive(Context context, Intent intent){ // コンテキストを取得 HogeActivity activity = (HogeActivity) context; // メソッドに渡す activity.getValue( intent.getStringExtra("test"), intent.getIntExtra("suji", 0) ) } }
なるほど。
流れを掴めば理解できると思いますが、やりたいこと以外の情報が多すぎるのと、
その先の情報がぶちぶち切れてて、結構時間がかかりました。
またServiceは生きたままでActivityが死んで、
再度アプリを立ち上げた際のロジックも考えて作らないと、
データに不整合が出る可能性もあるので、
結構頭を使います。
てことでちょっとテストしてみて、大丈夫ならGW中に更新したいと思っております!
気に入ったら押してね

~こんなアプリ出してます~








BLOG内検索


Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |


カテゴリー
ひとりごと(20)
Android(29)
MVNO(5)
Unity(3)
Lightwave(2)
Web(16)
Windows(8)
Music(4)
ラーメン(4)
料理レシピ(2)
株(3)
ポケモンGO(2)
SKYRIM(1)
ドラクエX(5)
Android(29)
MVNO(5)
Unity(3)
Lightwave(2)
Web(16)
Windows(8)
Music(4)
ラーメン(4)
料理レシピ(2)
株(3)
ポケモンGO(2)
SKYRIM(1)
ドラクエX(5)


