백그라운드 서비스에서 Android 활동의 정보를 업데이트하려면 어떻게 해야 하나요?

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

문제

정보 ActivityList가 있는 간단한 Android 애플리케이션을 만들려고 합니다. 애플리케이션이 시작되면 지속적으로 데이터를 계산하는 서비스를 시작할 계획이며(변경될 예정임) ActivityList가 동기화되기를 원합니다. 서비스가 앱 수명 동안 계산하는 데이터입니다.

서비스를 수신하도록 내 활동을 어떻게 설정합니까?이것이 이 문제에 접근하는 가장 좋은 방법입니까?

예를 들어, 주가 목록을 상상한다면 데이터는 정기적으로 변경되며 (내 경우에는) 데이터를 지속적으로 계산/가져오는 서비스와 동기화되어야 합니다.

미리 감사드립니다

도움이 되었습니까?

해결책

서비스를 듣기 위해 내 활동을 어떻게 설정할 수 있습니까? 이것이이 문제에 접근하는 가장 좋은 방법입니까?

내가 볼 수 있듯이 세 가지 주요 옵션이 있습니다.

  1. 투표. 그만큼 Activity 주기적으로 묻습니다 Service 최신 데이터의 경우. IMHO,이 옵션은 짜증나지만 확실히 가능합니다.

  2. 콜백. Jax의 대답에 따라 Activity 콜백 개체 ( "관찰자")를 Service. 그만큼 Service 데이터가 변경 될 때 콜백에서 메소드를 호출하여 UI가 업데이트됩니다. 당신은 그것을 사용하는 예를 볼 수 있습니다. Service 여기.

  3. 방송 Intents. 그만큼 Service 방송합니다 Intent ~을 통해 sendBroadcast() 데이터 변경에. 그만큼 Activity 등록 a BroadcastReceiver 사용 registerReceiver(), 그리고 그 BroadcastReceiver 들어오는 방송에 대한 통지가 있습니다. 이것은 트리거합니다 Activity 최신 데이터를로드합니다 Service, 또는 방송에서 Extras에서 최신 데이터를 얻기 위해 Intent. 당신은 그 기술을 사용하는 예를 볼 수 있습니다. Service 여기.

다른 팁

이것은 관찰자 패턴의 좋은 후보처럼 들립니다. 기본적으로 귀하의 활동 (관찰자)은 백그라운드 서비스 (관찰 가능한)에 자체적으로 등록되며 활동에서 데이터를 밀거나 가져올 수 있습니다. 이 경우 관찰자는 귀하의 활동이며 관찰 가능한 것은 귀하의 서비스가 될 것입니다.

디자인 패턴에 대해 아무것도 모른다면 "헤드 퍼스트 디자인 패턴"을 구매하면 읽기 쉽고 훌륭한 정보로 가득합니다.

추신 : 지금 읽고 있습니다.

나는 왜 아무도 아무도 어떤 라이브러리에서 이벤트 버스를 사용하여 간단한 접근법을 언급하지 않았는지 정말로 궁금합니다. 물론 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에 알릴 수 있는 기능이 필요합니다.

당신은 어떤 종류의 사용할 수 있습니다 어레이어댑터 데이터를 ListView로 가져옵니다.ArrayAdapter에는 다음과 같은 메소드가 있습니다. adpater.notifyDataSetChanged() 이 메서드를 호출할 때마다 어댑터는 해당 데이터가 변경되었음을 확인하고 다음 번에 업데이트해야 한다고 목록 보기에 알립니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top