3

Service이 파일을 다운로드 할 때 AsyncTask을 생성합니다. 액티비티에서는 Runnable 또는 Thread을 생성하여 Activity.runOnUiThread()으로 전달합니다. 서비스에서 해당 메서드에 액세스 할 수 없으므로 AsyncTask을 올바르게 사용하려면 어떻게해야합니까 (UI 스레드를 차단하지 않고 많은 작업 수행)? 서비스에만 응용 프로그램에서 호출됩니다, 당신은 그것을 싱글을 할 수있는 경우runOnUiThread()없이 서비스에서 AsyncTask를 생성/실행하는 방법

답변

2

,이 시도 :

public class FileDownloaderService extends Service implements FileDownloader { 
    private static FileDownloaderService instance; 

    public FileDownloaderService() { 
     if (instance != null) { 
      throw new IllegalStateException("This service is supposed to be a singleton"); 
     } 
    } 

    public static FileDownloaderService getInstance() { 
     // TODO: Make sure instance is not null! 
     return instance; 
    } 

    @Override 
    public void onCreate() { 
     instance = this; 
    } 

    @Override 
    public IBinder onBind(@SuppressWarnings("unused") Intent intent) { 
     return null; 
    } 

    @Override 
    public void downloadFile(URL from, File to, ProgressListener progressListener) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       // Perform the file download 
      } 
     }).start(); 
    } 
} 

지금 당신이 직접 서비스의 메소드를 호출 할 수 있습니다. 따라서 서비스를 작동 시키려면 downloadFile()으로 전화하십시오.

UI 업데이트 방법에 대한 질문. 이 메서드는 ProgressListener 인스턴스를받습니다. 그것은 다음과 같이 수 :

public interface ProgressListener { 
    void startDownloading(); 
    void downloadProgress(int progress); 
    void endOfDownload(); 
    void downloadFailed(); 
} 

지금 당신은 활동에서 UI를 업데이트 (안 UI의 모습을 어떻게 인식하지 못하고 남아있는 서비스에서).

+0

나는'public FileDownloaderService()'가'private'이어야한다고 생각합니다. 이것은 싱글 톤이 작동하는 방식입니다 ;-) – damienix

+0

몇 개월 전부터 자신의 코드를 보는 것은 재미 있습니다. 그리고 그것은 이미 당신에게보기 흉하게 보입니다 : -O. 당신 말이 맞아요, 사적이어야합니다. 하지만 OS가 무언가가없는 생성자를 사용하여 서비스를 생성하기 때문에 작동하지 않을 것이라고 생각합니다. 권리? – espinchi

+0

그것은 약간의 제안이었습니다. 나는 오히려 안드로이드 멍청이다.)하지만 인수없는 생성자를 사용하여 Sevice를 만드는 문제는 무엇인가? 알다시피,'AsyncTask'의'onProgressUpdate'는 UI를 업데이트 할 수 있으므로 아마도 더 나은 해결책이 될 수 있습니다. – damienix

관련 문제