2013-07-23 4 views
1

Im пытается выполнить некоторый параллон кода с потоками, используя задачу async. Но почему-то в android 4.2.2 не работает .... ....................AsyncTask in android 4.2.2

У меня есть этот код, который находится в основной класс:

new XmlDownloader(); 

task=new SendTask().execute(""); 

и следующие классы:

private class SendTask extends AsyncTask<String,String,String>{ 



     @Override 
     protected void onPreExecute(){ 

     } 

     @Override 
     protected String doInBackground(String...strings){ 

       while(true){        

        Log.w("outside", "hello"); 
      }    
      } 

      return strings[0]; 
     } 

     @Override 
     protected void onPostExecute(String country){ 


     } 
    } 

и

public class XmlDownloader extends Activity { 


public XmlDownloader(int pos) { 


    DownloaderTask task = new DownloaderTask(); 

    task.execute(""); 
} 


private String downloadXml(String s,int pos1) { 

    return null; 
} 


private class DownloaderTask extends AsyncTask<String, Void, String> { 

    public DownloaderTask() { 

    } 

    @Override 
    // Actual download method, run in the task thread 
    protected String doInBackground(String... params) { 

     while(true){ 
      Log.w("down", "asdasdasssasdasdasdasd"); 
      if(isCancelled()) 
       return null; 
     }; 


     return null; 

    } 

    @Override 
    // Once the image is downloaded, associates it to the imageView 
    protected void onPostExecute(String bitmap) { 


    } 
} 
} 

Я знаю его в то время как цикл, но голые с меня moment.In андроид 2.3.3 на LogCat показывает эту последовательность

Log.w("down", "asdasdasssasdasdasdasd"); 
Log.w("down", "asdasdasssasdasdasdasd"); 
Log.w("down", "asdasdasssasdasdasdasd");  
Log.w("outside", "hello"); 
Log.w("outside", "hello"); 
Log.w("down", "asdasdasssasdasdasdasd"); 

но андроид 4.2.2 показывает только

Log.w("down", "asdasdasssasdasdasdasd"); 
    Log.w("down", "asdasdasssasdasdasdasd"); 
    Log.w("down", "asdasdasssasdasdasdasd"); 
    Log.w("down", "asdasdasssasdasdasdasd"); 
    Log.w("down", "asdasdasssasdasdasdasd"); 

Любые идеи, почему темы не работают?

+1

Что именно вы подразумеваете под словом "не работает"? – asgs

+0

Последовательность неверна. Это похоже на последовательное выполнение, и я хочу выполнить параллельное выполнение.Что странно, потому что async создает потоки. Как я сказал в 2.3.3, отлично работает – Tony

+0

Посмотрите на мой ответ, я его отредактировал, и вы можете найти ответ на вопрос, почему это происходит ... сначала попробуйте запустить второй поток, и вы увидите напечатанную только другую строку. –

ответ

3

Использование AsyncTask может не дать вам истинный параллелизм, который вам нужен. В разных версиях Android число AsyncTask s, которое может работать одновременно, было изменено с 1 на 5, а затем на 1 (если я не ошибаюсь).

https://github.com/android/platform_frameworks_base/commits/master/core/java/android/os/AsyncTask.java

https://groups.google.com/forum/?fromgroups#!topic/android-developers/8M0RTFfO7-M

AsyncTask s подкреплены ThreadPool, над которыми вы не имеете никакого контроля. Если AsyncTask не соответствует вашим потребностям, необходимо использовать Службы или Loopers или создать свой собственный ThreadPoolExecutor. AsyncTask не предназначен для непрерывного цикла, то есть для сервера или службы.

Так что происходит в том, что в версии для Android выполняется только первый выделенный поток из пула, и поскольку он не завершается (они будут запускаться последовательно), второй никогда не запускается.

+0

Итак, что вы предлагаете, чтобы сделать это, чтобы сделать эту работу? – Tony

+0

Это зависит от того, что вы хотите сделать ... для этого примера для работы просто используйте две темы. Если вам нужно опубликовать в пользовательском интерфейсе, передайте обработчик потокам. ThreadPoolExecutor используется для управления тем, сколько потоков может выполняться одновременно и максимальное количество потоков, которые могут быть созданы. Как я уже сказал, он основан на ваших потребностях. –

+1

Существует также метод AsyncTask.executeOnExecutor (...), где вы можете указать свой собственный Исполнитель с несколькими потоками. – toto2

3

Это связано с тем, как AsyncTasks развивались с момента их разработки в API 3. В API 3 AsyncTasks (множественное число) выполнялись серийно. Это было изменено на пул потоков, позволяя нескольким AsyncTasks работать параллельно (API 4(DONUT)). Но, начиная с HONEYCOMB(API 11), AsyncTasks снова запускается серийно.

Глядя на выходе, которую вы предоставили, как SendTask & DownloaderTask выполняются параллельно в случае 2.3.3, который> DONUT и < Honeycomb. Но в случае 4.2.2 происходит серийное выполнение AsyncTasks. Так как сначала выполняется DownloaderTask, SendTask ожидает завершения его выполнения (чего не произойдет, пока (true)) -> следовательно, нет вывода.

С API 11 у вас есть выбор, независимо от того, выполняются ли ваши AsyncTasks серийно или параллельно. Для серийного исполнения используйте execute(Params... params). Для параллельного выполнения посмотрите на executeOnExecutor(Executor exec, Params... params).

+0

Хорошее объяснение. Благодаря! – asgs

Смежные вопросы