У меня есть эти два класса. Моя основная деятельность и тот , который расширяет AsyncTask
, сейчас в моей основной деятельности мне нужно , чтобы получить результат от OnPostExecute()
в AsyncTask
. Как я могу передать или получить результат в моей основной деятельности?
Вот примеры кодов.
Моя основная деятельность.
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
Это класс AsyncTask
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
android
android-asynctask
Стелла
источник
источник
Ответы:
Легко:
Создайте
interface
класс, гдеString output
необязательно, или может быть любые переменные, которые вы хотите вернуть.Перейдите в свой
AsyncTask
класс и объявите интерфейсAsyncResponse
как поле:В вашей основной деятельности вам нужно
implements
интерфейсAsyncResponse
.ОБНОВИТЬ
Я не знал, что это такой любимый для многих из вас. Итак, вот простой и удобный способ использования
interface
.все еще использую то же самое
interface
. К вашему сведению, вы можете объединить это вAsyncTask
классе.в
AsyncTask
классе:делай это в своем
Activity
классеИли снова реализовать интерфейс в Activity
Как вы можете видеть 2 решения выше, первое и третье, он должен создать метод
processFinish
, другое, метод находится внутри параметра вызывающего. Третий более аккуратный, потому что нет вложенного анонимного класса. Надеюсь это поможетСовет : Измените
String output
,String response
иString result
на разные подходящие типы, чтобы получить разные объекты.источник
Есть несколько вариантов:
Гнездо
AsyncTask
класс в вашемActivity
классе. Предполагая, что вы не используете одну и ту же задачу в нескольких действиях, это самый простой способ. Весь ваш код остается прежним, вы просто перемещаете существующий класс задач во вложенный класс внутри класса вашей деятельности.Создайте собственный конструктор,
AsyncTask
который будет ссылаться на вашActivity
. Вы могли бы создать задачу с чем-то вродеnew MyAsyncTask(this).execute(param1, param2)
.источник
static
? Просто используйте любойfieldOrMethod
изMyActivity
или,MyActivity.this.fieldOrMethod
если он затенен.MyAsyncTask
это не внутренний класс.private
/protected
для классов верхнего уровня не допускается, поэтому я подумал, что это неstatic
внутренний класс.Я чувствовал, что приведенный ниже подход очень прост.
Я объявил интерфейс для обратного вызова
Затем создается асинхронная задача для ответа на все типы параллельных запросов.
Затем вызывается асинхронная задача при нажатии кнопки в классе деятельности.
Спасибо
источник
Вы можете попробовать этот код в своем основном классе. Это сработало для меня, но я реализовал методы по-другому
источник
execute()
, посмотрите мой ответ, я добавил комментарий там. Вы можете проверить мой обновленный ответ. надеюсь это поможет.Этот ответ может быть поздно, но я хотел бы упомянуть несколько вещей, когда вы
Activity
зависитеAsyncTask
. Это поможет вам предотвратить сбои и управление памятью. Как уже упоминалось в ответах вышеinterface
, мы также называем их обратными вызовами. Они будут работать в качестве информатора, но никогда не будут посылать сильные ссылкиActivity
илиinterface
всегда будут использовать слабые ссылки в этих случаях.Пожалуйста, обратитесь к скриншоту ниже, чтобы узнать, как это может вызвать проблемы.
Как вы можете видеть, если мы начали
AsyncTask
с сильной ссылки, то нет никакой гарантии, что нашиActivity
/Fragment
будут живы, пока мы не получим данные, поэтому было бы лучше использоватьWeakReference
в этих случаях, и это также поможет в управлении памятью, поскольку мы никогда не будем держать сильная ссылка нашегоActivity
тогда будет иметь право на сборку мусора после его искажения.Ниже приведен фрагмент кода, чтобы узнать, как использовать классную WeakReference.
MyTaskInformer.java
Интерфейс, который будет работать как информер.MySmallAsyncTask.java
AsyncTask для выполнения длительной задачи, которую будет использоватьWeakReference
.MainActivity.java
Этот класс используется для запуска моейAsyncTask
реализацииinterface
этого класса иoverride
этого обязательного метода.источник
в вашем Oncreate ():
`
} `
источник
Вы можете сделать это в несколько строк, просто переопределите onPostExecute при вызове AsyncTask. Вот пример для вас:
Я надеюсь, что это помогло вам, счастливой кодировки :)
источник
onPostExecute
метод.Почему люди делают это так сложно.
Этого должно быть достаточно.
Не реализуйте onPostExecute в асинхронной задаче, а реализуйте его в Activity:
источник
@Override
?Вы можете вызвать
get()
методAsyncTask
(или перегруженget(long, TimeUnit)
). Этот метод будет блокировать до техAsyncTask
пор, пока не завершит свою работу, после чего он вернет вамResult
.Было бы разумно выполнять другую работу между созданием / запуском вашей асинхронной задачи и вызовом
get
метода, иначе вы не очень эффективно используете асинхронную задачу.источник
Вы можете написать свой собственный слушатель. Это то же самое, что и ответ HelmiB , но выглядит более естественно:
Создать интерфейс слушателя:
Затем напишите свою асинхронную задачу:
Наконец внедрите слушателя в действие:
И вот как вы можете вызвать asyncTask:
источник
Привет, вы можете сделать что-то вроде этого:
Создать класс, который реализует AsyncTask
Добавить в основной активности
источник
Создайте статический член в вашем классе Activity. Затем назначьте значение во время
onPostExecute
Например, если результатом вашего AsyncTask является String, создайте открытую статическую строку в вашем Activity
public static String dataFromAsyncTask;
Затем, в
onPostExecute
AsyncTask, просто сделайте статический вызов вашему основному классу и установите значение.MainActivity.dataFromAsyncTask = "result blah";
источник
Я делаю это с помощью потоков и обработчика / сообщения. Шаги следующим образом: объявить диалог
Создайте функцию, чтобы закрыть диалог после завершения операции.
Код вашей детализации:
источник
Вам необходимо использовать «протоколы» для делегирования или предоставления данных
AsynTask
.Делегаты и источники данных
Делегат - это объект, который действует от имени или в координации с другим объектом, когда этот объект встречает событие в программе. ( Определение Apple )
протоколы - это интерфейсы, которые определяют некоторые методы для делегирования некоторых типов поведения.
Вот полный пример !!!
источник
попробуй это:
И пример использования:
источник
Возможно, немного перегружен, но я предоставил обратные вызовы как для кода выполнения, так и для результатов. очевидно, для безопасности потоков вы хотите быть осторожными с тем, к чему вы обращаетесь при выполнении обратного вызова
Реализация AsyncTask:
Обратный звонок:
И, наконец, выполнение асинхронной задачи:
источник
Надеюсь, что вы прошли через это , если нет, пожалуйста, прочитайте.
https://developer.android.com/reference/android/os/AsyncTask
В зависимости от характера данных результатов, вы должны выбрать наилучший из возможных вариантов.
Это отличный выбор для использования интерфейса
некоторые другие варианты будут ..
Если класс AsyncTask определен внутри самого класса, в котором вы хотите использовать результат, в. Используйте статическую глобальную переменную или get () , используйте его из внешнего класса ( при необходимости переменная переменная ). но он должен знать о прогрессе AsyncTask или, по крайней мере, должен убедиться, что он завершил задачу, и результат доступен через метод глобальной переменной / get (). Вы можете использовать опрос, onProgressUpdate (Progress ...) , синхронизацию или интерфейсы (которые когда-либо подходят вам лучше всего)
Если результат совместим быть записью sharedPreference или это нормально быть сохранено в виде файла в памяти можно сохранить даже от самой фоновой задачи и может использовать onPostExecute () метод ,
чтобы получить уведомление , когда результат доступен в память.
Если строка достаточно мала и должна использоваться с началом действия. в onPostExecute () можно использовать намерения ( putExtra () ) , но помните, что с статическими контекстами работать не так безопасно .
Если возможно, вы можете вызывать статический метод из метода onPostExecute (), а результатом будет ваш параметр
источник