2017-12-05 1 views
0

Android 및 Java를 처음 사용합니다. 1000 개 이상의 이미지를 다운로드하려고합니다. 느리게 진행될 것이므로 UI 스레드에서이를 순차적으로 수행하고 싶지 않습니다. 따라서, 아래의 방식으로 thread와 runnable을 사용하여 multi-threading을 구현했습니다.Android에서 멀티 스레딩

for 루프는 1000 더하기라고합니다. 그래서 그것을 달성하는 효율적인 방법입니까? OS은 자체적으로 스레드 풀을 관리합니까?

private void syncS3Data() { 
    tStart = System.currentTimeMillis(); 
    try { 
     for (final AWSSyncFile f : awsSyncData.getFiles()) { 
      new Thread(new Runnable() { 

       @Override 
       public void run() { 
        beginDownload(f); 
       } 

      }).start(); 
     } 
    } catch (Exception ex) { 
     progressDialog.dismiss(); 
     showMessage("Error:" + ex.getStackTrace().toString()); 
    } 
} 
+0

Java의 솔루션을 구현하여 특정 양의 실행 파일 만 동시에 실행할 수 있습니다. Android에서는 특정 구현이 있는지 모릅니다. [newFixedThreadPool] (https : // docs.)와 같이 [스레드 풀] (https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html) (전체 주제가 읽기 좋습니다)을 참조하십시오. oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-) – AxelH

+0

많은 양의 데이터가있을 때 페이지 매김 기능을 사용하는 것이 좋습니다. asynctask –

+0

을 사용할 수 있습니다. 이미지 만 다운로드하려는 경우. 'glide' 라이브러리를 사용할 수도 있고 그렇게하기위한 라이브러리가 많이 있습니다. 그냥 구글. – Sunny

답변

2

물론 당신이 MainThread (UI 스레드) 당신이 한 경우, 응용 프로그램이 응답하지 않을 것이기 때문에 그렇게 할 수 없으며, 다음은 다음과 같습니다

당신은 AsyncTask를이 참조 사용할 수 있습니다 시스템에 의해 죽으면 AsyncTask 클래스를 사용하면 무엇이 필요한지 할 수 있지만 intentservice를 사용하는 것이 더 좋다. Intentservice는 작업자 스레드 (long 연산)이지만 Intentservice는 완료 될 때까지 아무 것도 실행하지 않는다. 현재 작업, 병렬로 다운로드해야하는 경우 서비스를 사용해야 함 UI 스레드와 작동하므로 작업 수행을 위해 asyncTask가 필요하지만 호출은 확실해야 함 ingentService와는 달리 stopSelf()는 intentService와는 달리 끝날 때 중지됩니다.

1

각 다운로드마다 스레드를 만드는 대신 하나의 스레드를 만들어 모든 이미지를 다운로드하는 데 사용하십시오. ... https://developer.android.com/reference/android/os/AsyncTask.html

private class DownloadFilesTask extends AsyncTask<SomeObject, Integer, Long> { 
    protected Long doInBackground(SomeObject... objs) { 

     for (final AWSSyncFile f : obj.getFiles()) { 
      beginDownload(f); 
     } 
    } 

    protected void onPostExecute(Long result) { 
     //Task Completed 
    } 

new DownloadFilesTask().execute(someObj); 
+0

AsyncTask에 대해 읽었습니다. 내가 이해할 수있는 한, 위의 방법은 모든 다운로드에 하나의 백그라운드 스레드 만 사용하므로 느려질 것입니다. 내가 틀렸다면 나를 바로 잡으십시오. –

+0

예, 각 파일에 대해 별도의 스레드를 만드는 것은 최적의 솔루션이 아닙니다. – dpaksoni

1

전자 상거래 응용 프로그램을 개발하기 전에 비슷한 문제가 발생하여 각 카테고리별로 200 개 이상의 이미지를 다운로드해야했습니다. AsyncTask 내에서 루프를 사용하고 각 다운로드가 완료된 후 이미지가 onProgessUpdate() 함수를 사용하여 관련 위치에 표시되었습니다. 실제 코드를 공유 할 수 없으므로 기본 예제를 제공합니다.

public class DownloadImages extends AsyncTask<String,String,String> 
{ 
    File image; 
    protected String doInBackground(String... params) 
    { 
     //download the image here and lets say its stored in the variable file 
     //call publishProgress() to run onProgressUpdate() 


    } 
    protected void onProgressUpdate(String... values) 
    { 
    //use the image in variable file to update the UI 
    } 
} 
+0

이렇게하려면 여러 개의 AsyncTask를 만들어야합니다. 나는 각각의 AsyncTask가 하나의 Thread와 동일하다는 것을 알고있다. AsyncTask 안에 for 루프를 넣는 것은 그리 효율적이지 않을 것이라고 나는 믿는다. –

+1

AsyncTask의 루프가 여러 개의 AsyncTasks (또는 threads)를 만드는 것보다 효율적이기 때문에 하나의 AsyncTask를 사용하여 루프를 그 안에 넣었습니다. –

+0

정말요? 그것이 단지 하나의 스레드 일 때 어떻게 될 수 있습니까? –