タコベルで行列とか本国でみたことない・・・


Noranekoです。



『これから英語は必要だ!』とか、


『これからは国際社会、海外に目を向けろ!』とか言う人に限って、


海外滞在とか全くなくて、パスポートすら持ってないのが現実だょ^ω^





でファストフードマスターの私に言わせれば、




IN-N-OUTしか認めません!





今秋に『Carl's Jr.』も来るみたいだけど、また行列するんだろうな・・・


でもCarl's Jr.はメニューが多くて、LAで滞在してた近くにあったので、


しょっちゅう行ってました^ω^






一応タバコと比較してます。




ということで、アメリカのファストフードとかのお話はまた今度にしましょう。


前回のお話の続きになります。


バックグラウンドで常駐させたい



いつのまにか死んでる



Serviceにすればいいよ!


と、ここまで理解してて、その後サンプルソースから大改造してみました。




できました。


重要なところをまとめてみます。


①Activity等からServiceを起動させる為にAIDLを作成する。


②Serviceからの戻り値をBroadcastReceiverで取得する。


③BroadcastReceiverからさらにActivityへ値を戻す。



①について、前回ほんのり書いてますが、


ActivityからServiceを独立させて呼び出す為に、AIDLファイルという物を作って


そこからServiceを呼びます。


下準備として、

MainService.java
public class MainService extends Service{
}


IService.aidl
interface IService {
}


AndroidManifest.xml
<service android:name=".MainService">
 <intent-filter>
  <action android:name="net.hoge.IService" />
 </intent-filter>
</service>



自分の目的では、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



<receiver
 android:name=".MainReceiver"
 android:exported="false">
< /receiver>

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
BLOG内検索
<< 2015/04 >>
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