1

私はAsyncTask自分の一部で使用してFragmentおりActivity、これらはうまく機能します。しかし問題は、タスク実行時に戻るボタンを押すか、アプリを終了すると、Asynchronousアプリがクラッシュすることです。これは私の丸太猫です:

08-16 08:15:34.032: E/AndroidRuntime(21957): FATAL EXCEPTION: main
08-16 08:15:34.032: E/AndroidRuntime(21957): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at me.kaidul.uhunt.MainActivity.selectItem(MainActivity.java:434)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at me.kaidul.uhunt.MainActivity.access$0(MainActivity.java:387)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at me.kaidul.uhunt.MainActivity$GetProblemListTask.onPostExecute(MainActivity.java:680)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at me.kaidul.uhunt.MainActivity$GetProblemListTask.onPostExecute(MainActivity.java:1)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.os.AsyncTask.finish(AsyncTask.java:417)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.os.AsyncTask.access$300(AsyncTask.java:127)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.os.Looper.loop(Looper.java:123)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at android.app.ActivityThread.main(ActivityThread.java:4627)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at java.lang.reflect.Method.invokeNative(Native Method)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at java.lang.reflect.Method.invoke(Method.java:521)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-16 08:15:34.032: E/AndroidRuntime(21957):    at dalvik.system.NativeStart.main(Native Method)

AsyncTask戻るボタンを押したり、アプリを終了したりしなくても適切に機能しているため、ここにコードを追加していません。私はすべてのAsyncTaskようなものを新しいGetTaskDone().execute(parameter)と呼び、すべての中にありonPostExecuteますAsycTask

アプリのクラッシュを回避するにはどうすればよいですか?

編集:

今、私は考えています、問題はAsyncTask. AsyncTaskバックプレス/終了に関係なく、私の他の人は働いているからです。

これは問題のある AsyncTask です。

保護されたクラス GetProblemListTask は AsyncTask を拡張します {

@Override
protected Void doInBackground(String... params) {
    InputStreamReader isr = null;
    if (hasConnection) {
        Date date = new Date();
        long savedTime = prefs.getLong(CommonUtils.LAST_SAVED,
                date.getTime());
        long now = date.getTime();
        if (now - savedTime > fiveDays
                || (now - savedTime <= fiveDays && prefs.getBoolean(
                        CommonUtils.problemListisCached, false) == false)) {
            if (CommonUtils.isDebuggable) {
                Log.d("updating", "need to update!");
            }
            prefs.edit()
                    .putBoolean(CommonUtils.problemListisCached, false)
                    .commit();
            isr = new JSONDownloader().getJSONStringFromUrl(params[0]);
            BufferedReader br = new BufferedReader(isr, bufferSize);
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (IOException e) {
                Log.d("problem", "in file writting");
            }
            writeToFile(sb.toString(), CommonUtils.FILE_PROBLEM_LIST);
            prefs.edit()
                    .putBoolean(CommonUtils.problemListisCached, true)
                    .commit();
            try {
                isr.close();
            } catch (IOException e) {
                if (CommonUtils.isDebuggable) {
                    Log.d("isr", e.toString());
                }
            }
            try {
                br.close();
            } catch (IOException e) {
                if (CommonUtils.isDebuggable) {
                    Log.d("br", e.toString());
                }
            }
            prefs.edit().putLong(CommonUtils.LAST_SAVED, now).commit();
        } else {
            if (CommonUtils.isDebuggable) {
                Log.d("old_copy", "Old copy is rendering");
            }
            try {
                isr = new InputStreamReader(
                        openFileInput(CommonUtils.FILE_PROBLEM_LIST));
            } catch (FileNotFoundException e) {
                Log.d("file_not_found", "File is missing!");
            }
        }
    } else {
        try {
            isr = new InputStreamReader(
                    openFileInput(CommonUtils.FILE_PROBLEM_LIST));
        } catch (FileNotFoundException e) {
            Log.d("file_not_found", "File is missing!");
        }
    }
    if (CommonUtils.isDebuggable) {
        Log.d("start", "mapping start");
    }
    try {
        isr = new InputStreamReader(
                openFileInput(CommonUtils.FILE_PROBLEM_LIST));
    } catch (FileNotFoundException e1) {

    }
    JsonReader reader = new JsonReader(isr);
    try {
        reader.beginArray();
        while (reader.hasNext()) {
            reader.beginArray();
            problems.put(
                    reader.nextInt(),
                    new Problems(reader.nextString(), reader
                            .nextString(), reader.nextInt()));
            while (reader.hasNext())
                reader.skipValue();
            reader.endArray();
        }
        reader.endArray();
        reader.close();
    } catch (IOException e) {
        if (CommonUtils.isDebuggable) {
            Log.d("problems", "hashmaping problem");
        }
    }
    return null;
}

@Override
protected void onPostExecute(Void result) {
    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 // this is selecItem() function. It's task is to add a fragment to the activity. 
    selectItem(0);
    if (CommonUtils.isDebuggable) {
        Log.d("successful", "eventually survived!");
    }
}

}

4

1 に答える 1

3

AsyncTaskは UI スレッドonPreExecuteで実行されます。onPostExecute現在 AsyncTask のインスタンスを保持しておらず、フラグメント/アクティビティの でキャンセルを呼び出していると仮定していますonDestroy

それを追加するか、アプリが表示されるかどうかを示すブール値フラグを追加します (API 17 が導入されましActivity.isDestroyed()た。API レベル >= 17 を使用している場合は、単にそれを使用します)。

注: AsyncTask をキャンセルする呼び出しを追加する場合でも、次の行に沿って何かを呼び出す必要があります。

if(isCancelled()) { return; }

あなたの冒頭にonPostExecute

編集:isCancelled()メソッドのより完全な例:

あなたの活動で:

protected void onDestroy() {
    super.onDestroy();

    if(task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
        task.cancel(true);
    }
}

次に、タスクをクラス全体の変数に割り当てます。実行task =中の行に追加するだけnew AsyncTask().execute();で、現在とまったく同じように機能します。

AsyncTask.cancel()のドキュメントによると、実際には onPostExecute が呼び出されないことが保証されているため、isCancelled()前述のようにチェックインする必要さえありません。

于 2013-08-16T01:46:28.523 に答える