Galaxy s iii AsyncTask未正确执行

时间:2013-01-01 19:51:45

标签: android android-asynctask android-4.0-ice-cream-sandwich

我正在使用asynctask进行蓝牙套接字通信。它在galaxy s ii(android 2.3.3)上工作正常,但有时不适用于galaxy s iii(android 4.0.4)。

class MyTask extends AsyncTask<Void, long[], Void> {
     long[] d = new long[40];

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.e("BTtest", "MyTask preexecute");
    }

    @Override
    protected Void doInBackground(Void... v) {
        int count = 0;
        Log.e("BTtest", "Mytask background start " );
            *******creting socket and streams*******
                    *********logic*******
                    publishProgress(d);
            }


    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        **logic**           
    }

    @Override
    protected void onProgressUpdate(long[]... data) {
        super.onProgressUpdate(data);
                    *******logic***
        }

}

来自onCreate按钮功能:

mt = new MyTask();
mt.execute( );

有时在galaxy s iii上调用onPreExecute方法并且doInBackground方法未启动。 但其他时候称为背景方法。它看起来像是随机的。

有什么想法吗?

wildhemp建议只在一个线程中执行asynctasks。我在一个活动中编写了测试应用程序这3个asynctasks:

public class MainActivity extends Activity {

 MyTask mt1, mt2, mt3;
  TextView tvInfo;

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    tvInfo = (TextView) findViewById(R.id.tvInfo);
  }

  public void onclick(View v) {
        mt1 = new MyTask();
        mt1.execute("file_path_1", "file_path_2", "file_path_3", "file_path_4");
        mt2 = new MyTask();
        mt2.execute("file_path_1", "file_path_2", "file_path_3", "file_path_4");
        mt3 = new MyTask();
        mt3.execute("file_path_1", "file_path_2", "file_path_3", "file_path_4");
  }

  class MyTask extends AsyncTask<String, Integer, Void> {

    @Override
    protected void onPreExecute() {
      super.onPreExecute();
      tvInfo.append("Begin \n");
    }

    @Override
    protected Void doInBackground(String... urls) {
      try {
        int cnt = 0;
        for (String url : urls) {
          downloadFile(url);
          publishProgress(++cnt);
        }

      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return null;
    }


    @Override
    protected void onProgressUpdate(Integer... values) {
      super.onProgressUpdate(values);
      tvInfo.append("Downloaded " + values[0] + " files \n");
    }

    @Override
    protected void onPostExecute(Void result) {
      super.onPostExecute(result);
      tvInfo.append("End\n");
    }


    private void downloadFile(String url) throws InterruptedException {
      int i=0;
      while (i<100000000){
          i+=1;
      }
    }
  }
} 

它在sgs2,sgs3和模拟器上工作正常。应用程序在sgs3上加载75%(4个核心上的3个线程)的cpu。 sgs2加载100%(2个核心上的3个线程)。 这意味着每个asynctask在separeted线程中执行的是什么。

问题解决了。谢谢。 我已经更改了项目目标构建版本。 现在执行代码:

                    mt = new MyTask();

                    if (Build.VERSION.SDK_INT >= 11){
                        mt.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR); //work on sgs3 android 4.0.4
                    }
                    else {
                        mt.execute(); // work on sgs2 android 2.3
                    }

1 个答案:

答案 0 :(得分:0)

可能会发生因为4.0.4上的doInBackground默认使用1个线程来运行所有异步任务,所以如果另一个doInBackground仍在工作,它将阻止执行,我认为在这种情况下将调用onPreExecute,因为它在主线程上运行。在2.3.3中,asynctask使用更多线程(AFAIK是每个任务的新线程)。

更新: 以下是android documentation所说的内容:

  

首次引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,这被改为一个线程池,允许多个任务并行运行。从HONEYCOMB开始,任务在单个线程上执行,以避免由并行执行引起的常见应用程序错误。

     

如果您真的想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。