Что эриксон сказал лучше всего. Вот связанный вопрос и ответ нить - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html
Библиотека Apache BCEL позволяет вам читать классы без их загрузки. Я считаю, что это будет быстрее, потому что вы сможете пропустить этап проверки. Другая проблема с загрузкой всех классов с помощью загрузчика классов заключается в том, что вы будете испытывать огромное влияние на память, а также непреднамеренно запускать любые статические блоки кода, которые вы, вероятно, не хотите делать.
Ссылка на библиотеку Apache BCEL - http://jakarta.apache.org/bcel/
В большинстве случаев вы должны просто игнорировать такие отчеты, если активность уже уничтожена.
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();
}
});
}
}
Может быть, не лучшее решение, но ... Этот код перезапускает загрузчик каждый раз, что плохо, но работает только вокруг, если вы хотите использовать загрузчик.
Loader l = getLoaderManager().getLoader(MY_LOADER);
if (l != null) {
getLoaderManager().restartLoader(MY_LOADER, null, this);
} else {
getLoaderManager().initLoader(MY_LOADER, null, this);
}
Кстати. Я использую Cursorloader ...
Возможное решение - запустить AsyncTask в пользовательском одноэлементном объекте и получить доступ к результату onFinished () из одноэлементного объекта в своей деятельности. Каждый раз, когда вы поворачиваете экран, нажимаете onPause () или onResume (), будет использоваться / доступен самый последний результат. Если у вас по-прежнему нет результата в вашем одноэлементном объекте, вы знаете, что он все еще занят или что вы можете перезапустить задачу.
Другой подход заключается в работе с сервисной шиной, такой как Otto, или с сервисом.
Хорошо, я пытаюсь понять это, извините, если я что-то неправильно понял, но вы теряете ссылки на что-то, когда устройство вращается.
Принимая удар ...
добавит ли
android:configChanges="orientation|keyboardHidden|screenSize"
в манифест для этой операции исправление вашей ошибки? или помешать onLoadFinished()
сказать, что деятельность остановлена?