2017-12-24 4 views
0

활동에서 서비스를 시작한 다음 활동이 종료되거나 종료 될 때도 서비스를 계속 실행하려고합니다. 그런 다음 앱 활동을 다시 시작하면 기존 서비스에 다시 연결됩니다.활동이 파괴되면 서비스가 자멸하는 이유는 무엇입니까?

나는 bindService에 대한 문서를 읽었지만 뒤로 버튼을 눌러 활동을 종료 할 때마다 서비스의 onUnBind가 자동으로 서비스를 효과적으로 종료한다고합니다. 서비스가 언 바운드되기 전에 수동으로 unbindService를 호출해야한다고 생각했습니다.

일단 Activity가 삭제되면 새로운 Activity가 생성되면 멤버 변수 mService, mBound 및 tv가 다시 채워 져야하므로 밑의 간단한 코드에서 "bindService started"가 표시된다는 사실을 놀랍지 않습니다.하지만 LocalService 인스턴스 내의 모든 멤버 변수는 같고 변경되지 않으므로 "bindService가 이미 시작되었습니다."Val = "+ mService.myval;은 새로운 활동을 다시 시작할 때마다 동일하게 유지해야합니까?

MainActivity

public class MainActivity extends AppCompatActivity 
{ 
    LocalService mService; 
    Boolean mBound = false; 
    TextView tv; 

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

     tv = (TextView)findViewById(R.id.textView);  
    } 

    @Override 
    protected void onStart() 
    { 
     super.onStart(); 
    } 

    @Override 
    protected void onStop() 
    { 
     super.onStop(); 
    } 

    @Override 
    protected void onDestroy() 
    { 
     super.onDestroy(); 
    } 

    public void onButtonStart(View v) 
    { 
     String str; 

     // Bind to LocalService 
     if (!mBound) 
     { 
      Intent intent = new Intent(this, LocalService.class); 

      if (!bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) 
      { 
       unbindService(mConnection); 
       str = "bindService failed?!"; 
      } 
      else 
      { 
       str = "bindService started."; 
      } 
     } 
     else 
      str = "bindService already Started. Val = " + mService.myval; 

     tv.setText(str); 
    } 

    public void onButtonStop(View v) 
    { 
     if (mBound) 
     { 
      mService.stop(); 
      unbindService(mConnection); 
      mBound = false; 

      tv.setText("Stopped Service"); 
     } 
     else 
      tv.setText("Service is not running"); 
    } 

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

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

LocalService를

public class LocalService extends Service 
{ 
    private final IBinder mBinder = new LocalBinder(); 
    private final Random mGenerator = new Random(); 
    public int myval = getRandomNumber(); 

    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
    } 

    // Service is being Destroyed 
    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 
    } 

    public int getRandomNumber() 
    { 
     return mGenerator.nextInt(100); 
    } 

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

    // Client is Unbinding via the unbindService() call 
    @Override 
    public boolean onUnbind(Intent intent) 
    { 
     return super.onUnbind(intent); 
    } 

    public class LocalBinder extends Binder 
    { 
     public LocalService getService() 
     { 
      return LocalService.this; 
     } 
    } 
} 

답변

1

"당신은 startService (..)와 안드로이드 서비스를 시작하면 명시 적으로 stopService를 호출 할 때까지 서비스 (실행 유지됩니다 .. 서비스가 시스템에 의해 실행될 수있는 두 가지 이유가 있습니다 : 누군가가 Context.startService()를 호출하면 시스템은 서비스를 검색합니다 (생성하고 cal 필요한 경우 onCreate() 메서드를 호출 한 다음 클라이언트가 제공 한 인수로 onStartCommand (Intent, int, int) 메서드를 호출합니다. 이 시점에서 Context.stopService() 또는 stopSelf()가 호출 될 때까지 서비스가 계속 실행됩니다. Context.startService()에 대한 여러 호출은 중첩되지 않으며 (onStartCommand()에 대한 해당 호출이 여러 번 발생하지만), 시작된 횟수에 관계없이 서비스는 한 번 중지됩니다. Context.stopService() 또는 stopSelf()가 호출됩니다. 그러나 서비스는 stopSelf (int) 메소드를 사용하여 시작된 인 텐트가 처리 될 때까지 서비스가 중지되지 않도록 보장 할 수 있습니다.

클라이언트는 Context.bindService()를 사용하여 서비스에 대한 지속적인 연결을 얻을 수도 있습니다. 이것은 서비스가 아직 실행 중이 지 않을 때 (onCreate()를 호출하는 동안) 서비스를 생성하지만 onStartCommand()는 호출하지 않습니다. 클라이언트는 서비스가 onBind (Intent) 메소드에서 반환하는 IBinder 객체를 수신하여 클라이언트가 다시 서비스에 콜백 할 수있게합니다. 연결이 설정된 동안에는 서비스가 계속 실행됩니다 (클라이언트가 서비스의 IBinder에 대한 참조를 유지하는지 여부에 관계없이). 일반적으로 반환 된 IBinder는 AIDL로 작성된 복잡한 인터페이스 용입니다.

서비스를 시작하고 연결을 바인딩 할 수 있습니다. 이 경우 시스템은 서비스가 시작되거나 Context.BIND_AUTO_CREATE 플래그로 하나 이상의 연결이있는 한 서비스를 계속 실행합니다. 이러한 상황이 발생하지 않으면 서비스의 onDestroy() 메서드가 호출되고 서비스가 효과적으로 종료됩니다. 모든 정리 (수신기를 등록 취소, 스레드를 정지)들의 OnDestroy()에서 반환에 완료해야합니다. "

0

당신이 bindService()를 사용하고 난 볼 수 있듯이.

바운드 서비스는 일반적으로 만 사는 것이 다른 응용 프로그램을 제공하면서 구성 요소이며 백그라운드에서 무기한 실행되지 않습니다.

활동 (서비스에 바인딩 된)이 완료되면 서비스가 더 이상 실행되지 않습니다.

서비스를 다시 실행하려면 STICKY 서비스를 작성하고 START_STICKY 플래그가 있어야합니다.

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    // Do your task here 
    return START_STICKY; 
} 

START_STICKY 서비스는 활동이없는 상태에서 백그라운드로 실행할 수 있습니다. 그리고 콜백으로 서비스와 통신 할 수 있습니다.

Sticky service을 작성하려면 Service을 읽으십시오.

관련 문제