2012-10-17 4 views
3

내 환경 설정 화면에서 환경 설정 중 하나를 클릭하면 인터넷에서 파일을 다운로드하는 서비스를 시작하고 싶습니다. 서비스가 이미 실행중인 경우 (파일 다운로드) 서비스를 중지해야합니다 (다운로드 취소).onDestroy()가 실행 된 후 IntentService onHandleIntent()가 계속 실행 중입니다.

public class Setting extends PreferenceActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    downloadPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { 

     @Override 
     public boolean onPreferenceClick(Preference pref) { 
      if (DownloadService.isRunning) { 
       Setting.this.stopService(new Intent(Setting.this, 
        DownloadService.class)); 
      } else { 
       Setting.this.startService(new Intent(Setting.this, 
        DownloadService.class)); 
      } 
      return false; 
     } 
    }); 
    } 
} 

서비스 클래스 :

public class DownloadService extends IntentService { 

public static final int DOWNLOAD_SUCCESS = 0; 
public static final int DOWNLOAD_FAIL = 1; 
public static final int DOWNLOAD_CANCELLED = 2; 
public static final int SERVER_FAIL = 3; 

public static boolean isRunning = false; 
private int result; 

public DownloadService() { 
    super("DownloadService"); 
} 

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

@Override 
protected void onHandleIntent(Intent intent) { 
    if (NetworkStateUtils.isInternetConnected(getApplicationContext())) 
     result = downloadFiles(getApplicationContext()); 

} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    switch (result) { 
    case DOWNLOAD_SUCCESS: 
     Toast.makeText(getApplicationContext(), R.string.download_finished, 
       Toast.LENGTH_SHORT).show(); 
     break; 
    case DOWNLOAD_CANCELLED: 
     Toast.makeText(getApplicationContext(), R.string.download_canceled, 
       Toast.LENGTH_SHORT).show(); 
     break; 
    case DOWNLOAD_FAIL: 
     Toast.makeText(getApplicationContext(), R.string.download_failed, 
       Toast.LENGTH_SHORT).show(); 
     break; 
    } 
    isRunning = false; 
} 
} 

이 서비스는 다운로드가 완료 될 때까지 실행하기위한 것입니다. downloadFiles() 함수는 AsyncTask을 사용하지 않습니다. FileOutputStream과 함께 HttpURLConnection을 직접 저장할 수 있습니다.

환경 설정을 클릭하면 서비스가 올바르게 시작됩니다. 이제 문제는 stopService()으로 서비스를 중지하려면 DownloadServiceonDestroy()을 즉시 트리거하는 것입니다. 그러나 로그에 따르면 여전히 HTTP 요청을 계속 볼 수 있기 때문에 onHandleIntent()이 계속 실행 중입니다. Service이 스레드 자체에서 실행되기 때문입니까? 아니면 제가 잘못하고 있습니까? stopService()이 호출 될 때 onHandleIntent()의 모든 항목이 즉시 중지되도록 (또는 적어도 중지 할 수 있도록) 어떻게 할 수 있습니까?

답변

6

마지막으로 어떻게 작동시키는 지 알아 냈습니다.

제 질문에 언급했듯이, 어떻게 든 onHandleIntent()가 작업을 수행 할 스레드를 생성합니다. 따라서 서비스 자체가 소멸되는 경우에도 스레드는 여전히 실행 중입니다. 전역 변수를 추가하여 목표를 달성했습니다.

private static boolean isStopped = false; 

~ DownloadService 클래스를 추가하여 목표를 달성했습니다. 대신

Setting.this.stopService(new Intent(Setting.this, DownloadService.class)); 

를 호출, 내 서비스를 취소하기 위해

DownloadService.isStopped = true을 설정합니다.

마지막으로 onHandleIntent()에서 작업하는 동안이 부울을 주기적으로 확인하여 다운로드를 중지해야하는지 확인하십시오. isStopped = true 인 경우 즉시 반환하면 서비스가 중단됩니다.

희망 사항은이 문제를 해결하는 데 도움이되기를 바랍니다. 그리고이 질문을 읽어 주셔서 감사합니다.

+3

이'isStopped' 변수를 숨기려면'onDestroy'에서 true로 설정하는 것을 고려하십시오. – xorgate

+0

isStopped 변수는 public이어야합니다. 코드 스 니펫은이를 개인용으로 설정합니다. – v01d

3

작업을 수행하는 데 별도의 스레드가 있으며, 수행중인 작업에 따라 즉시 중지 할 수 없습니다. I/O에서 블로킹하는 경우 인터럽트가 적용되지 않습니다.

관련 문제