バックグラウンドサービスから Android アクティビティの情報を更新するにはどうすればよいですか

StackOverflow https://stackoverflow.com/questions/2468874

質問

情報の ActivityList を持つ単純な Android アプリケーションを作成しようとしています。アプリケーションの起動時に、データを常に計算するサービス (データは変化します) を開始する予定で、ActivityList を同期させたいと考えています。サービスがアプリの存続期間中に計算するデータ。

サービスをリッスンするようにアクティビティを設定するにはどうすればよいですか?これはこの問題に対処する最善の方法でしょうか?

たとえば、株価のリストを想像すると、データは定期的に変更されるため、データを常に計算/取得している (私の場合は) サービスと同期する必要があります。

前もって感謝します

役に立ちましたか?

解決

アクティビティを次のように設定するにはどうすればよいですか? サービスを聞いていますか?これは、 この問題にアプローチする最善の方法は?

私が思うに、主な選択肢は 3 つあります。

  1. 投票。の Activity 定期的に質問します Service 最新のデータについては。私見ですが、このオプションは最悪ですが、確かに可能です。

  2. コールバック。ジャックスの答えによれば、 Activity コールバック オブジェクト (「オブザーバー」) を Service. 。の Service データが変更されるとコールバックでメソッドを呼び出し、それによって UI が更新されます。それを使用する例を見ることができます Service ここ.

  3. 放送 Intents. 。の Service を放送します Intent 経由 sendBroadcast() データ変更について。の Activity を登録します BroadcastReceiver を使用して registerReceiver(), 、そしてそれ BroadcastReceiver ブロードキャストの受信が通知されます。これにより、 Activity 最新のデータを Service, 、あるいは単に放送のエキストラから最新データを取得するためかもしれません Intent. 。このテクニックを使用した例は、 Service ここ.

他のヒント

Observerパターンの良い候補のように

この音。基本的にはあなたの活動(オブザーバー)は、バックグラウンドサービス(観測)に自身を登録しますと、あなたのアクティビティからデータをプッシュまたはプルすることができます。この場合、あなたのオブザーバーは、あなたの活動となり、観測は、あなたのサービスになります。

あなたはデザインパターンについて何も知らない「ヘッドファーストデザインパターン」を購入する場合は、

、それが読みやすいですし、偉大な情報がいっぱいです。

PS:私は今、それを読んでいます。

誰がどんなライブラリでEventBusを使用して簡単なアプローチを言及しない理由

私は本当に、本当に疑問に思って。あなたはRXを使用していない場合、これは、もちろんです。 私の個人的なお気に入りはGreenRobotでEventBusです。 https://github.com/greenrobot/EventBusする

ちょうどコードの行の結合、および無インターフェースと。イベントを発生し、あなたが好きな場所、それを聞きます。それはそれは、スレッドセーフである、切り離され、そしてそれはあなたのアプリケーションがクラッシュすることはありません。

あなたは、実行中のサービスとの活動を結合して、それとの通信にbindService()を使用する必要があります。

public class BindingActivity extends Activity {
YourService mService;
boolean mBound = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

@Override
protected void onStart() {
    super.onStart();
    // Bind to Your Service
    Intent intent = new Intent(this, YourService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
}

/** Called when a button is clicked (the button in the layout file attaches to
  * this method with the android:onClick attribute) */
public void onButtonClick(View v) {
    if (mBound) {
        // Call a method from your Service.
        // However, if this call were something that might hang, then this request should
        // occur in a separate thread to avoid slowing down the activity performance.
        int num = mService.getRandomNumber();
        Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
    }
}

/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // We've bound to the running Service, cast the IBinder and get instance
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
 };
}

など、あなたのサービス:

public class LocalService extends Service {
    // Binder given to clients
   private final IBinder mBinder = new LocalBinder();
   // Random number generator
   private final Random mGenerator = new Random();

/**
 * Class used for the client Binder.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with IPC.
 */
public class LocalBinder extends Binder {
    LocalService getService() {
        // Return this instance of LocalService so clients can call public methods
        return LocalService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

/** method for clients */
public int getRandomNumber() {
  return mGenerator.nextInt(100);
  }
}

あなたは、リスト内の変化を算出し、バックグラウンドスレッドを実行しています。このスレッドは現在、リストが更新されたGUIを通知する可能性を必要とします。

あなたは ArrayAdapterするのいくつかの種類を使用することができますリストビューにデータを取得します。 ArrayAdapterは特殊なアダプタと呼ばれる方法があります。 notifyDataSetChanged()のあなたは、このメソッドを呼び出すたびに、アダプターは、対応するデータが変更されたことを確認し、それが次の可能性を更新する必要があり、リストビューを通知します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top