2010-03-18 5 views
37

정보의 ActivityList가있는 간단한 Android 애플리케이션을 만들려고합니다. 애플리케이션이 시작될 때 지속적으로 데이터를 계산할 서비스를 시작할 계획입니다. (변경 될 예정입니다.) ActivityList가 서비스 수명 기간 동안 계산중인 데이터와 동기화되도록하고 싶습니다.백그라운드 서비스에서 Android 활동의 정보를 업데이트하는 방법

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

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

미리 감사드립니다.

답변

91

서비스를 수신하려면 으로 내 활동을 어떻게 설정할 수 있습니까? 이 문제에 접근하는 가장 좋은 방법은 입니까?

  1. 폴링 : 내가보기로

당신은 세 가지 주요 옵션이 있습니다. Activity은 주기적으로 Service에게 최신 데이터를 요청합니다. IMHO,이 옵션은 짜증나지만, 확실히 가능합니다.

  • 콜백. jax의 답변에 따르면 ActivityService이라는 콜백 객체 ("관찰자")를 등록합니다. Service은 데이터가 변경되면 콜백에서 메서드를 호출하고 UI를 업데이트합니다. 당신은 Servicehere과 함께 그것을 사용하는 예를 볼 수 있습니다.

  • 브로드 캐스트 Intents. Service은 데이터 변경시 을 통해 sendBroadcast()을 통해 브로드 캐스트합니다. ActivityregisterReceiver()을 사용하여 BroadcastReceiver을 등록하고 수신되는 브로드 캐스트를 BroadcastReceiver에 알립니다. 이로 인해 ActivityService에서 최신 데이터를로드하거나, 방금 Intent의 추가 정보에서 최신 데이터를 가져옵니다.이 기술을 사용하는 예가 Servicehere 인 것을 볼 수 있습니다.

  • +11

    숫자 3의 중대한보기 ... http://www.websmithing.com/2011/02/01/how-to-update-the-ui-in-an-android-activity-using-data-from- a-background-service/ –

    +1

    응용 프로그램을 닫으면 어떻게됩니까? 상태 활동으로 AlarmManager를 실행하는 경우 어떻게 처리 할 수 ​​있습니까? – Basbous

    +2

    기술 2와 3의 장단점은 무엇입니까? –

    4

    이 소리는 옵서버 패턴에 대한 좋은 후보와 같습니다. 기본적으로 귀하의 활동 (The Observer)은 백그라운드 서비스 (The Observable)에 등록되며 귀하는 귀하의 활동에서 데이터를 밀거나 당길 수 있습니다. 귀하의 옵서버는 귀하의 활동이 될 것이며 Observable은 귀하의 서비스가 될 것입니다.

    "Head First Design Patterns"을 구입하는 디자인 패턴에 대해 잘 모르는 독자는 읽기 쉽고 훌륭한 정보로 가득합니다.

    추신 : 나는 그것을 지금 읽고 있습니다.

    +8

    네가 맞아.하지만이 대답은 안드로이드에만 국한된 것이 아니다 ... – Janusz

    0

    목록의 변경 사항을 계산하는 백그라운드 스레드가 실행됩니다. 이 스레드는 이제 목록이 업데이트되었음을 ​​GUI에 알릴 필요가 있습니다.

    어떤 종류의 ArrayAdapter을 사용하여 ListView에 데이터를 가져올 수 있습니다. ArrayAdapter에는 adpater.notifyDataSetChanged() 메서드가 있습니다.이 메서드를 호출 할 때마다 어댑터는 해당 데이터가 변경된 것을 확인한 후 다음 번에 업데이트해야한다고 listview에 알립니다.

    +2

    'ArrayAdapter'를 사용하려고한다면'add()','insert()','remove() 메소드를 호출하여 내용을 변경합니다. 그렇다면'notifyDataSetChanged()'는 필요 없다. – CommonsWare

    0

    실행중인 서비스와 활동을 바인드하고 통신하려면 bindService()를 사용해야합니다. 아무도 어떤 라이브러리에 의해 EventBus를 사용하여 간단한 방법을 언급하지 왜 정말 궁금 정말입니다

    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); 
        } 
    } 
    
    +0

    이것은 OP가 요구 한 것이 아닙니다. 이것이 가능할 수도 있지만 (서비스가 지속적으로 데이터를 업데이트하고 UI가 새 데이터를 요청할 수 있음) 사용자 입력 (예 : 버튼 누름)에 대한 반응으로 UI 측에서 호출해야합니다. 그 반대의 질문은 UI가 서비스의 새 데이터로 지속적으로 업데이트 할 수있는 방법을 요청합니다. –

    0

    : 같은

    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; 
        } 
    }; 
    } 
    

    과 서비스를 제공합니다. RX를 사용하지 않는 경우 물론입니다. 개인적으로 가장 좋아하는 곳은 GreenRobot의 EventBus입니다. https://github.com/greenrobot/EventBus

    몇 줄의 코드와 인터페이스가 없습니다. 이벤트를 시작하고 원하는 곳마다들을 수 있습니다. 그것은 분리되어 있으며 스레드로부터 안전하며 응용 프로그램을 손상시키지 않습니다.

    관련 문제