質問

この質問にはすでに答えがあります:

Asynctaskクラスに問題があります。 4つまたは5つのタスクを作成した後、私のタスクは動作を停止するようです。

2つのアクティビティがあります。画像activityと呼ばれる2番目のアクティビティを開始するボタンのみを保持するMainActivity。

画像診断は非常に単純です。レイアウトを設定するOnCreateを取得し、インターネットから画像をロードする新しいAsynctaskを起動します。これは最初の数回正常に機能します。しかし、それは突然機能しなくなります。 Onpreexecuteメソッドは毎回実行されますが、Doinbackgroundメソッドは実行されません。私は眠っているループでdoinbackgroundを簡素化しようとしましたが、同じことが起こります。 Asynctaskはキャンセルされ、Ondestroyメソッドでnullに設定されているため、この行動を理解することはできません。そのため、新しい画像診断を開始するたびに、新鮮な非同期も作成します。

バックボタンを押して画像耳の反応性とタスクを再作成し、MainActivityのボタンをクリックするよりも再作成します。

誰かがいますか?私は本当にこれに苦労しています。

更新:イメージアクティビティを開始するコード(ボタン内のonclickListener)

Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.setClassName(this, ImageActivity.class.getName());
startActivity(intent);

上記のコードはこのアクティビティを開始します

    public class ImageActivity extends Activity {

    private AsyncTask<Void, Void, Void> task;

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

        task = new AsyncTask<Void, Void, Void>() {

            @Override
            protected void onPreExecute()
            {
                Log.d(TAG, "onPreExecute()");
            }

            @Override
            protected Void doInBackground(Void... params)
            {
                Log.d(TAG, "doInBackground() -- Here is the download");
                // downloadBitmap("http://mydomain.com/image.jpg")
                return null;
            }

            @Override
            protected void onPostExecute(Void res)
            {
                Log.d(TAG, "onPostExecute()");
                if(isCancelled()){
                    return;
                }
            }
        }.execute();
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        task.cancel(true);
    }
}

アップデート:

従来のスレッドとrononuithreadメソッドの組み合わせを使用してテストしましたが、うまく機能しているようです。これで、スレッドは毎回実行されます。

役に立ちましたか?

解決

asynctaskを削除し、aを使用します 従来のスレッド と組み合わせる代わりに rononuithread うまくいくようです。しかし、私はまだAsynctaskが非常に「不安定」である理由を見つけていません。

これが私のために働くコードです:

public class ImageActivity extends Activity {

    private Thread worker;

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

        worker = new Thread(new Runnable(){

            private void updateUI(final List<Object> list)
            {
                if(worker.isInterrupted()){
                    return;
                }
                runOnUiThread(new Runnable(){

                    @Override
                    public void run()
                    {
                        // Update view and remove loading spinner etc...
                    }
                });
            }

            private List<Object> download()
            {
                // Simulate download
                SystemClock.sleep(1000);
                return new ArrayList<Object>();
            }

            @Override
            public void run()
            {
                Log.d(TAG, "Thread run()");
                updateUI(download());
            }

        });
        worker.start(); }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        worker.interrupt();
    }
}

他のヒント

同様の問題に遭遇しました。 SDK 11まで並行して複数の非同期を実行することはできません。 詳細については、こちらをご覧ください

私もこの問題に出くわしました。使用する場合 AsyncTask.execute, 、タスクはシリアルキューで実行されます(Android 4.3ソースから):

最初に導入されたとき、非同期は単一のバックグラウンドスレッドで連続して実行されました。ドーナツから始めて、これはスレッドのプールに変更され、複数のタスクが並行して動作できるようになりました。ハニカムから始めて、タスクは単一のスレッドで実行され、並列実行によって引き起こされる一般的なアプリケーションエラーを回避します。

これは私が見た行動と一致しています。私は持っていました AsyncTask ダイアログをポップアップしました doInBackground ダイアログが閉じられるまでブロックされました。ダイアログには独自のものが必要でした AsyncTask 完了する。ダイアログ AsyncTask.doInBackground オリジナルのためにメソッドは実行されませんでした AsyncTask まだブロックされていました。

解決策は、2番目を実行することです AsyncTask 別のもの Executor.

TraceViewを使用して調査するか、スレッドダンプを取得します。私の推測では、あなたのAsynctaskスレッドの1つがダウンロード時にぶら下がっています。

Asynctaskには小さなスレッドプールがあるため、タスクの1つが垂れ下がっている場合、スレッドプールをブロックする可能性があります。

実行できるクイックテストは次のとおりです。4.3では、実行できるスレッドが5つしかないことがわかります。 1つのスレッドが終了すると、他のスレッドが起動します。

  private void testAsyncTasks() {

        for (int i = 1; i <= 10; i++) {
              final int tid = i;
              new AsyncTask<Integer, Void, Void>() {
                    protected void onPreExecute() {
                          Log.d("ASYNCTASK", "Pre execute for task : " + tid);
                    };

                    @Override
                    protected Void doInBackground(Integer... args) {
                          int taskid = args[0];
                          long started = SystemClock.elapsedRealtime();
                          Log.d("ASYNCTASK", "Executing task: " + taskid + " at " + started);
                          for (int j = 1; j <= 20; j++) {
                                Log.d("ASYNCTASK", "   task " + taskid + ", time=" + (SystemClock.elapsedRealtime() - started));
                                SystemClock.sleep(1000);
                          }
                          return null;
                    }

                    protected void onPostExecute(Void result) {
                          Log.d("ASYNCTASK", "Post execute for task : " + tid);
                    };
              }.execute(i);

        }
  }

Androidのハウスキーピングスレッドは、システムによって管理されているため、心配する必要はありません。

画像ダウンロード方法も投稿してください。また、ondestroy()メソッドのスレッドをキャンセルしないようにしましたか?画像をUIスレッドにどのように返していますか?

私が信じている問題は、重い画像のダウンロードタスクです。 Asyncタスクをキャンセルしても、画像のダウンロードは引き続き実行され、ダウンロードが完了するまでAsyncタスクは終了しません。ダウンロード中にAynctaskでISCancelled()メソッドを確認し、タスクがキャンセルされた場合はダウンロードを殺します。

参照のために、cancel()メソッドのドキュメントが表示されます。このタスクの実行をキャンセルしようとします。この試みは、タスクが既に完了した、すでにキャンセルされている、または他の理由でキャンセルできなかった場合に失敗します。成功し、キャンセルが呼び出されたときにこのタスクが開始されていない場合、このタスクは実行されないはずです。タスクが既に開始されている場合、May interntrumpifrunningパラメーターは、このタスクを実行するスレッドがタスクを停止しようとして中断するかどうかを決定します。このメソッドを呼び出すと、doinbackground(object [])返品後にoncancelled(オブジェクト)がUIスレッドに呼び出されます。この方法を呼び出すと、OnPostExecute(オブジェクト)が呼び出されないことが保証されます。この方法を呼び出した後、Doinbackground(Object [])から定期的にIsCancelled()によって返された値を確認して、できるだけ早くタスクを完了する必要があります。

私もこれを持っていました、始めない本当の理由はありませんでした。 ADBを再起動した後、再び機能したことに気付きました。なぜこれがなぜなのかわからないが、それは私のために働いた

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top