0

Bluetoothソケット通信に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( );

ギャラクシーでは、iii onPreExecuteメソッドが呼び出され、doInBackgroundメソッドが開始されない場合があります。しかし、バックグラウンドメソッドが呼び出されることもあります。ランダムに見えます。

何か案は?

wildhempは、1つのスレッドでのみ実行される非同期タスクを提案しました。私はテストアプリケーションにこの3つの非同期タスクを1つのアクティビティで作成しました。

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スレッド)。これは、すべての非同期タスクが分離されたスレッドで実行されたことを意味します。

問題が解決しました。ありがとう。プロジェクトのターゲットビルドバージョンを変更しました。今すぐコードを実行する:

                    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
                    }
4

1 に答える 1

0

これは、4.0.4 の doInBackground がデフォルトで 1 つのスレッドを使用してすべての非同期タスクを実行しているために発生する可能性があるため、別の doInBackground がまだ機能している場合、実行がブロックされます。この場合、onPreExecute が呼び出されると思います。メインスレッドで実行されます。2.3.3 では、asynctask はより多くのスレッドを使用します (私の知る限り、タスクごとに新しいスレッドが使用されます)。

更新: Android のドキュメントには次のように記載されています。

最初に導入されたとき、AsyncTasks は単一のバックグラウンド スレッドでシリアルに実行されました。DONUT 以降、これはスレッドのプールに変更され、複数のタスクが並行して動作できるようになりました。HONEYCOMB 以降、並列実行によって発生する一般的なアプリケーション エラーを回避するために、タスクは単一のスレッドで実行されます。

本当に並列実行が必要な場合は、THREAD_POOL_EXECUTOR を使用して executeOnExecutor(java.util.concurrent.Executor, Object[]) を呼び出すことができます。

于 2013-01-01T19:59:18.897 に答える