Компенсация недостатков AsyncTask с помощью BetterAsyncTask (Droid-Fu)
После долгого и безуспешного поиска в Google выяснилось, что практически нет информации о удобной библиотеке под названием Droid-Fu https://github.com/kaeppler/droid-fu
После прочтения введения создателем ( http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/) или API ( http://kaeppler.github.com/droid-fu), я не мог понять, как определить новую betterasynctask (какие методы содержат какую информацию и т. д.).
Поэтому, если есть кто-нибудь, кто может предоставить мне (и, в частности, другим) полезный исходный код или учебные пособия, я был бы очень признателен!
(Если вам нужен файл jar проекта, дайте мне знать, я могу выслать вам копию)
РЕДАКТИРОВАТЬ:
Хороший пример можно найти здесь! и здесь
Хорошо, вот некоторая дополнительная информация, которую я нашел в исходном коде:
- Диалог прогресса отображается автоматически. Смотрите useCustomDialog(), disableDialog()
- Если исключение выдается изнутри doInBackground, это теперь обрабатывается методом handleError.
- Теперь вы должны больше переопределять onPreExecute(), doInBackground() и onPostExecute(), вместо этого вы должны использовать before(), doCheckedInBackground() и after() соответственно.
Давайте посмотрим, чего я смогу достичь с этого момента... все еще ищу рабочий пример!
РЕДАКТИРОВАТЬ 2:
Несколько примеров можно найти здесь и здесь. Я придерживаюсь этого, но я получаю ошибку. Разница лишь в том, что моя AsyncTask определяется не внутри действия, а как отдельный класс. Пошаговое выполнение кода показывает, что ошибка возникает при создании (встроенного в AsyncTask) диалога.
Это моя трассировка стека:
через минуту
2 ответа
Droid-fu сейчас немного устарел, в основном из-за отсутствия поддержки Fragment. Но я приведу пример из приложения, которое я написал, который использовал его.
Во-первых, ваш класс активности должен иметь подкласс BetterActivity (или BetterXXXActivity). В моем коде я использовал ListActivity, поэтому мои здесь подклассы BetterListActivity. Я также определяю подкласс BetterAsyncTask, чтобы я мог расширить некоторые функции.
public class DroidFuExample extends BetterListActivity {
private ExampleTask mTask;
private List<Stuff> mMainStuff;
private class ExampleTask extends BetterAsyncTask<Void, Void, Integer> {
private List<Stuff> mStuff;
private DroidFuExample mContext; // a context for lifecycle management
...
}
}
Теперь моей задаче не нужен параметр, используется неопределенный диалог, поэтому прогресс не публикуется, и необходимо вернуть целое число. Ваши потребности могут отличаться, и это влияет на типы, используемые в определении класса.
Следующим шагом является определение того, что задача обрабатывает в фоновом режиме. В моем случае мне нужно заполнить mStuff. В своем классе задач определите либо doInBackground(), либо doCheckedInBackground() (doChecked... может вызвать исключение, если вы хотите его перехватить).
protected Integer doCheckedInBackground(Context context, Void... params)
throws Exception {
mStuff = // some long-running code (no longer on the UI thread)
return 1;
}
Наконец, по крайней мере, вам нужно что-то сделать со своим результатом, например обновить переменную класса или заполнить пользовательский интерфейс или что-то еще. Это сделано в after
:
protected void after(Context context, Integer integer) {
if (integer >= someAcceptablePositiveConstant) {
mMainStuff = mStuff;
doSomethingInTheUIWithMainStuff();
} else {
//gah!
}
}
Как вы уже упоминали, с классом можно сделать больше, например определить before()
переопределение, которое работает в потоке пользовательского интерфейса перед задачей, или failed()
/ handleError()
обрабатывать непроверенные / проверенные сбои. Это всего лишь простой пример, надеюсь, это поможет.
Какая боль в @ss! Ошибка была хорошо спрятана внутри класса BetterActivityHelper:
public static ProgressDialog createProgressDialog(final Activity activity,
int progressDialogTitleId, int progressDialogMsgId) {
ProgressDialog progressDialog = new ProgressDialog(activity);
if (progressDialogTitleId <= 0) {
progressDialogTitleId = activity.getResources().getIdentifier(
PROGRESS_DIALOG_TITLE_RESOURCE, "string", activity.getPackageName());
}
progressDialog.setTitle(progressDialogTitleId);
if (progressDialogMsgId <= 0) {
progressDialogMsgId = activity.getResources().getIdentifier(
PROGRESS_DIALOG_MESSAGE_RESOURCE, "string", activity.getPackageName());
}
progressDialog.setMessage(activity.getString(progressDialogMsgId));
progressDialog.setIndeterminate(true);
progressDialog.setOnKeyListener(new OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
activity.onKeyDown(keyCode, event);
return false;
}
});
progressDialogTitleId и progressDialogMsgId ожидают значения внутри res/values /string.xml:
<!-- Droid-Fu Progressdialog -->
<string name="droidfu_progress_dialog_title">Some nasty dialog title</string>
<string name="droidfu_progress_dialog_message">Some funny message</string>
Если они не определены, будет сгенерировано исключение времени выполнения.
К сожалению, даже самые лучшие вспомогательные классы практически бесполезны, если они НЕ УКАЗАНЫ. Мне потребовалось пару часов, чтобы понять, что пошло не так. Итак, еще раз, нет, спасибо разработчику. Сор