#java #android
#java #Android
Вопрос:
Кажется, что в каждом учебном пособии, которое я нахожу, вместо ExecutorService используется AsyncTask (устаревший). Я прошел курс Java на Udemy, и они также использовали AsyncTask для всего. Вот один класс, с которым я работаю:
public class FetchURL extends AsyncTask<String, Void, String> {
Context mContext;
String directionMode = "driving";
public FetchURL(Context mContext) {
this.mContext = mContext;
}
@Override
protected String doInBackground(String... strings) {
// For storing data from web service
String data = "";
directionMode = strings[1];
try {
// Fetching the data from web service
data = downloadUrl(strings[0]);
Log.d("mylog", "Background task data " data.toString());
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
PointsParser parserTask = new PointsParser(mContext, directionMode);
// Invokes the thread for parsing the JSON data
parserTask.execute(s);
}
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
Log.d("mylog", "Downloaded URL: " data.toString());
br.close();
} catch (Exception e) {
Log.d("mylog", "Exception downloading URL: " e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
}
и я бы действительно хотел использовать ExecutorService, как здесь, вместо AsyncTask. Я бьюсь головой о стену и, похоже, не могу привести правильные аргументы, и эта штука работает.
Ответ №1:
Замените свой AsyncTask
на Runnable
:
public class FetchUrl implements Runnable {
public interface Callback {
void onSuccess(String data);
void onFailure(Exception e);
}
private String url;
private WeakReference<Callback> callbackWeakReference;
public FetchUrl(String url, Callback callback) {
this.url = url;
this.callbackWeakReference = new WeakReference<>(callback);
}
@Override
public void run() {
try {
String data = downloadUrl(url);
Callback callback = callbackWeakReference.get();
if (callback != null) {
callback.onSuccess(data);
}
} catch (Exception e) {
Callback callback = callbackWeakReference.get();
if (callback != null) {
callback.onFailure(e);
}
}
}
... // include your downloadUrl function
}
Затем создайте и отправьте его в ExecutorService
:
FetchUrl.Callback callback = new FetchUrl.Callback() {
@Override
public void onSuccess(String data) {
// handle your data
}
@Override
public void onFailure(Exception e) {
// handle the exception
}
};
Runnable job = new FetchUrl(url, callback);
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.submit(job);
Обратите внимание, что я использовал WeakReference<Callback>
, потому что код в вашем обратном вызове содержит ссылку на Context
и может вызвать Context
утечки.
submit()
Функция возвращает Future
для управления отправленным заданием. Это удобно, если вы хотите отменить задание или дождаться его завершения (блокируя текущий поток). Последний вариант использования, возможно, предпочел бы использовать Callable<Result>
вместо Runnable
, потому что вызывающий поток может обработать исключение, и обратный вызов не будет использоваться, что сделает ваш код более кратким.
Также не забудьте вызвать shutdown()
свой ExecutorService
, когда вам это больше не нужно.
Комментарии:
1. Спасибо за это, но, похоже, это не работает. Я не получаю свою ломаную линию для указаний. Я предполагаю, что это потому, что я не включаю свою функцию onpostexecute, но как бы я это реализовал?
2. Вы обрабатываете это в обратном вызове onSuccess (), где вы получаете свои данные обратно. Если возможно, выполняйте как можно больше тяжелой работы в фоновом режиме, поэтому, возможно, выполните синтаксический анализ также в
Runnable
и верните вашу полилинию в качестве конечного результата.