6

Asynctask クラスを使用した Android のアプリで作業しています。2.3.5 で実行されている Android デバイスでテストしたときに正常に動作しますが、直面している問題は、同じことがタブレット 4.0.4 でも機能しないことです。

テスト中に、 preexecute() が呼び出されているが doInbackground() が呼び出されていないことを知りましたが、デバイス(2.3.5)で doInbackground() が呼び出されています。

この問題の原因の 1 つは、タブレットのプロセッサがデバイスのプロセッサよりもはるかに高速であるため、スレッドの問題である可能性があります。これに取り組むために、いくつかのフラグを使用し、Thread.sleep() を使用しました。 do while ループで、条件が true のときに機能するようにしますが、運が悪く、ループ自体で立ち往生しています。これが私のコードです:

MyAsyncTask object = new MyAsyncTask (MainActivity.this);
runOnUiThread(new Runnable() {
    public void run() {         

        try {
            if (object.isReady() || !object.isStarting()) {
                return;
            }

            object.execute();

            do {
                Thread.sleep(1000);             
            } while (!object.isReady() && object.isStarting());

            if(!object.isReady()) { 
                return;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }           
});

非同期タスククラス:

public class MyAsyncTask extends AsyncTask<Void, Void, Boolean>{

    private ProgressDialog dialog;
    private Context context;
    private boolean isStarting = false;
    private boolean isReady = false;


    public AsyncUpdatesofJquery(Context context) {
        this.context = context;
        isStarting = true;
        isReady = false;
    }

    public boolean isStarting() {
        return isStarting;
    }

    public boolean isReady() {
        return isReady;
    }

    @Override
    protected void onPreExecute() {

        isStarting = true;
        isReady = false;
        dialog = new ProgressDialog(context); 
        dialog.setMessage("Downloading Files, Please wait...");
        dialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... params) {

        isReady = true;
        isStarting = false;
        downloadFiles(context); // my background task

        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        context.startActivity(new Intent(context, NewActivity.class));
        dialog.dismiss();
        isReady = false;
        isStarting = false;

    }
}
4

1 に答える 1

17

マルチスレッドモデルが2.3.5と4.0.4の間で変更されました。 AsyncTask現在、デフォルトでは、同じスレッドを使用するアプリケーション内のすべてのサブクラスがあります(つまり、一度に実行できるAsyncTaskは1つだけです!)。ここで説明されています:

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

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

そのことを念頭に置いて、別AsyncTaskのアプリが実行されている可能性があります。これにより、このアプリが起動しなくなります。これは、2.3.5デバイスでは正常に動作するが、4.0.4タブレットでは正常に動作しない理由を説明します。

于 2012-10-12T19:03:44.353 に答える