AsyncTaskLoader onLoad Завершено с отложенной задачей и изменением конфигурации

Что эриксон сказал лучше всего. Вот связанный вопрос и ответ нить - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html

Библиотека Apache BCEL позволяет вам читать классы без их загрузки. Я считаю, что это будет быстрее, потому что вы сможете пропустить этап проверки. Другая проблема с загрузкой всех классов с помощью загрузчика классов заключается в том, что вы будете испытывать огромное влияние на память, а также непреднамеренно запускать любые статические блоки кода, которые вы, вероятно, не хотите делать.

Ссылка на библиотеку Apache BCEL - http://jakarta.apache.org/bcel/

24
задан Paul Blessing 18 July 2012 в 03:48
поделиться

4 ответа

В большинстве случаев вы должны просто игнорировать такие отчеты, если активность уже уничтожена.

public void onLoadFinished(Loader<String> loader, String data) {
    Log.d("DemoActivity", "onLoadFinished reporting to activity " + myActivityId);
    if (isDestroyed()) {
       Log.i("DemoActivity", "Activity already destroyed, report ignored: " + data);
       return;
    }
    resultFragment.setResultText(data);
}

Также вы должны вставить проверку isDestroyed() во все внутренние классы. Runnable - это наиболее часто используемый случай.

Например:

// UI thread
final Handler handler = new Handler();
Executor someExecutorService = ... ;
someExecutorService.execute(new Runnable() {
    public void run() {
        // some heavy operations
        ...
        // notification to UI thread
        handler.post(new Runnable() {
            // this runnable can link to 'dead' activity or any outer instance
            if (isDestroyed()) {
                return;
            }

            // we are alive
            onSomeHeavyOperationFinished();
        });
    }
});

Но в таких случаях лучше всего избегать передачи сильной ссылки на Activity в другой поток (AsynkTask, Loader, Executor и т. Д.).

Наиболее надежное решение здесь:

// BackgroundExecutor.java
public class BackgroundExecutor {
    private static final Executor instance = Executors.newSingleThreadExecutor();

    public static void execute(Runnable command) {
        instance.execute(command);
    }
}

// MyActivity.java
public class MyActivity extends Activity {
    // Some callback method from any button you want
    public void onSomeButtonClicked() {
        // Show toast or progress bar if needed

        // Start your heavy operation
        BackgroundExecutor.execute(new SomeHeavyOperation(this));
    }

    public void onSomeHeavyOperationFinished() {
        if (isDestroyed()) {
            return;
        }

        // Hide progress bar, update UI
    }
}

// SomeHeavyOperation.java
public class SomeHeavyOperation implements Runnable {
    private final WeakReference<MyActivity> ref;

    public SomeHeavyOperation(MyActivity owner) {
        // Unlike inner class we do not store strong reference to Activity here
        this.ref = new WeakReference<MyActivity>(owner);
    }

    public void run() {
        // Perform your heavy operation
        // ...
        // Done!

        // It's time to notify Activity
        final MyActivity owner = ref.get();
        // Already died reference
        if (owner == null) return;

        // Perform notification in UI thread
        owner.runOnUiThread(new Runnable() {
            public void run() {
                owner.onSomeHeavyOperationFinished();
            }
        });
    }
}
2
ответ дан Oleksii K. 18 July 2012 в 03:48
поделиться

Может быть, не лучшее решение, но ... Этот код перезапускает загрузчик каждый раз, что плохо, но работает только вокруг, если вы хотите использовать загрузчик.

Loader l = getLoaderManager().getLoader(MY_LOADER);
if (l != null) {
    getLoaderManager().restartLoader(MY_LOADER, null, this);
} else {
    getLoaderManager().initLoader(MY_LOADER, null, this);
}

Кстати. Я использую Cursorloader ...

0
ответ дан Gordon Freeman 18 July 2012 в 03:48
поделиться

Возможное решение - запустить AsyncTask в пользовательском одноэлементном объекте и получить доступ к результату onFinished () из одноэлементного объекта в своей деятельности. Каждый раз, когда вы поворачиваете экран, нажимаете onPause () или onResume (), будет использоваться / доступен самый последний результат. Если у вас по-прежнему нет результата в вашем одноэлементном объекте, вы знаете, что он все еще занят или что вы можете перезапустить задачу.

Другой подход заключается в работе с сервисной шиной, такой как Otto, или с сервисом.

0
ответ дан josomers 18 July 2012 в 03:48
поделиться

Хорошо, я пытаюсь понять это, извините, если я что-то неправильно понял, но вы теряете ссылки на что-то, когда устройство вращается.

Принимая удар ...

добавит ли

android:configChanges="orientation|keyboardHidden|screenSize"

в манифест для этой операции исправление вашей ошибки? или помешать onLoadFinished() сказать, что деятельность остановлена?

-2
ответ дан StrikeForceZero 18 July 2012 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: