40

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

サービスをリッスンするようにアクティビティを設定するにはどうすればよいですか?これはこの問題に取り組むための最良の方法ですか?

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

前もって感謝します

4

5 に答える 5

95

サービスをリッスンするようにアクティビティを設定するにはどうすればよいですか?これはこの問題に取り組むための最良の方法ですか?

私が見ているように、3つの主要なオプションがあります。

  1. ポーリング。Activity定期的Serviceに最新のデータを要求します。私見、このオプションは最悪ですが、それは確かに可能です。

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

  3. 放送IntentsServiceブロードキャストは、データ変更時にビアをブロードキャストIntentします。を使用してsendBroadcast()登録しActivity、着信ブロードキャストが通知されます。これにより、がトリガーされ、から最新のデータが読み込まれるか、ブロードキャストのエクストラから最新のデータが取得される可能性があります。ここでそのテクニックを使用した例を見ることができます。BroadcastReceiverregisterReceiver()BroadcastReceiverActivityServiceIntentService

于 2010-03-18T12:10:11.843 に答える
4

これは、オブザーバーパターンの良い候補のように聞こえます。基本的に、アクティビティ(オブザーバー)はバックグラウンドサービス(オブザーバブル)に登録され、アクティビティからデータをプッシュまたはプルできます。この場合、オブザーバーがアクティビティになり、オブザーバブルがサービスになります。

デザインパターンについて何も知らない場合は、「Head First Design Patterns」を購入すると、読みやすく、優れた情報が満載です。

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

于 2010-03-18T10:33:18.397 に答える
2

私は本当に、本当に、どのライブラリでもEventBusを使用する単純なアプローチについて誰も言及しなかったのか疑問に思っています。もちろん、これはRXを使用していない場合です。私の個人的なお気に入りはGreenRobotのEventBusです。 https://github.com/greenrobot/EventBus

ほんの数行のコードで、インターフェースはありません。イベントを発生させ、好きな場所でそれを聞いてください。分離されており、スレッドセーフであり、アプリをクラッシュさせることはありません。

于 2017-03-08T21:00:49.247 に答える
1

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);
  }
}
于 2015-03-20T13:31:19.140 に答える
0

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

ある種のArrayAdapterを使用して、データをListViewに取り込むことができます。ArrayAdapterには、adpater.notifyDataSetChanged()というメソッドがあります。このメソッドを呼び出すたびに、アダプターは対応するデータが変更されたことを確認し、次の可能性で更新する必要があることをリストビューに通知します。

于 2010-03-18T10:51:00.280 に答える