Я использую ASyncTask
в своем приложении для получения данных (короткий URL) через REST API из веб-службы (Bitly).
Когда ASyncTask
завершится, я хочупередать результат обратно в мой MainActivity
.
Получение данных обратно в MainActivity
достигается с помощью onPostExecute
метода AsyncTask
.
, который я прочитали прочитайте и прочитайте о том, как это сделать, и, кажется, есть два основных подхода.
Первоначально я использовал подход «WeakReference», в котором в начале класса AsyncTask
вы создаете слабую ссылку на вашMainActivity
следующим образом:
private class getShortURL extends AsyncTask<String, Void, String> {
private WeakReference<MainActivity> mainActivityWeakReference;
myASyncTask(MainActivity activity) {
mainActivityWeakReference = new WeakReference<>(activity);
}
{etc etc}
При таком подходе ваш класс AsyncTask
находится за пределами вашего класса MainActivity
, поэтому на многие вещи необходимо ссылаться по слабой ссылке.
Это работало нормально (за исключением того, что я подозревал - возможно, неправильно - что эта слабая ссылка могла быть причиной случайных NPE), но затем я нашел другой способ сделать что-то.
Этот второй подход включал перемещение ASyncTask
класс внутри MainActivity
классаs.
Таким образом, я смог получить доступ ко всему, что было доступно в классе MainActivity
напрямую, включая элементы и методы пользовательского интерфейса, определенные в MainActivity
. Это также означает, что я могу получить доступ к таким ресурсам, как строки и т. Д., И могу сгенерировать toasts
, чтобы сообщить пользователю, что происходит.
В этом случае весь код WeakReference
, приведенный выше, может быть удален, а *Класс 1036 * можно сделать приватным.
Затем я также могу делать такие вещи прямо в onPostExecute
или сохранять это в методе в MainActivity
, который я могу вызвать напрямую из onPostExecute
: shorten_progress_bar.setIndeterminate (false);shorten_progress_bar.setVisibility (View.INVISIBLE);
if (!shortURL.equals("")) {
// Set the link URL to the new short URL
short_link_url.setText(shortURL);
} else {
CommonFuncs.showMessage(getApplicationContext(), getString(R.string.unable_to_shorten_link));
short_link_url.setHint(R.string.unable_to_shorten_link);
}
(обратите внимание, что CommonFuncs.showMessage()
- это моя собственная оболочка для функции тоста, чтобы упростить вызов).
НО, Android Studioзатем выдает предупреждение о том, что «класс AsyncTask
должен быть статическим, иначе могут возникнуть утечки».
Если я сделаю метод статическим, я получу предупреждение о том, что метод из MainActivity
, который я хочу вызватьиз onPostExecute
нельзя вызвать, так как он нестатический.
Если я сделаю этот метод из MainActivity
статическим методом, то он не сможет получить доступ к строковым ресурсам и любым другим методам, которые не являются статичными - и не работаюткроличья нора, я иду!
То же самое верно, как и следовало ожидать, если бы я просто переместил код из метода в MainActivity
в метод onPostExecute
. Итак ...
- Является ли использование AsyncTask как нестатического метода действительно плохо? (Кажется, мое приложение работает нормально с этим предупреждением в AS, но я, очевидно, не хочу создавать утечку памяти в моем приложении.
- Является ли appraoch
WeakReference
на самом деле более правильным и безопасным подходом? - Если я использую подход
WeakReference
, как я могу создавать такие вещи, как toasts
, которые нужно запускать в потоке пользовательского интерфейса и получать доступ к строковым ресурсам и т. Д. Из MainActivity
?
Я где-то читал о создании interface
, но немного растерялся и не смог найти его снова. Кроме того, это не будет иметь такую же зависимость от MainActivity
, что WeakReference
делает и состоит в том, чтоплохо?
Я действительно ищу рекомендации по передовой практике о том, как вернуть некоторые данные в MainActivity
и поток пользовательского интерфейса из AsyncTask
, который безопасен и не рискует утечки памяти.