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中に更新したいと思っております!




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

authored by Noraneko | Comment(0) | Android
コメント


お名前*

Email Address

URL

コメント*

BLOG内検索
<< 2018/10 >>
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