Всем привет!
Хочу поделится одним маленьким трюком для начинающих андроидописателей. Этот трюк стар как мир и сам я раньше многократно им пользовался, но поскольку основная моя работа с андроидом никак не связана, то за давностью лет я его подзабыл и вот на днях был вынужден его срочно вспоминать.
Понадобилось мне сделать микро-приложение, задача которого проста до безобразия: получить данные с вебсервиса и отобразить их на экране в виде списка. Казалось бы, что может быть проще? Но есть одно «но», точнее, этих «но» даже несколько.
Во-первых, все операции, выполнение которых, может занять неопределенное количество времени (а сюда относятся все операции с сетью), должны выполнятся в отдельном потоке. Android SDK предоставляет нам как минимум два варианта решения этого вопроса, один из которых (и на мой взгляд самый правильный) — это AsyncTask. Так, с этим понятно. Идем дальше.
Вторая и самая главная проблема — как вернуть результат работы с сетью в наш основной поток, что бы показать его на экране? Ну давайте разбираться… Что мы знаем про AsyncTask из того, что могло бы нам помочь? А знаем мы то, что его метод onPostExecute выполняется в основном потоке! Этот факт дает нам как минимум два варианта решения проблемы. Номер раз — мы попросту можем передать наш графический контроль (в моем случае это ListView) в AsyncTask параметром и заполнить его данными на onPostExecute. Этот вариант чаще всего встречается в интернете в качестве примера решения нашей задачи. И номер два — вариант который дает нам большую гибкость — это использование делегата. Тут конечно тоже есть несколько вариантов, но я рассмотрю только один из них, который мне больше всех нравится.
Пора переходить от слов к делу!
Итак, для начала мы создадим интерфейс в котором будет всего один метод:
Теперь имплементируем этот интерфейс в нашу activity:
Ну а теперь пришла пора AsyncTask:
Обратите внимание на конструктор! Тут мы получаем нашего делегата и сохраняем его.
Теперь все практически готово, осталось только запустить наш механизм из нашей activity:
Как видите ничего революционного, чисто и просто. Надеюсь, что я кому-нибудь сэкономил время.
Хочу поделится одним маленьким трюком для начинающих андроидописателей. Этот трюк стар как мир и сам я раньше многократно им пользовался, но поскольку основная моя работа с андроидом никак не связана, то за давностью лет я его подзабыл и вот на днях был вынужден его срочно вспоминать.
Понадобилось мне сделать микро-приложение, задача которого проста до безобразия: получить данные с вебсервиса и отобразить их на экране в виде списка. Казалось бы, что может быть проще? Но есть одно «но», точнее, этих «но» даже несколько.
Во-первых, все операции, выполнение которых, может занять неопределенное количество времени (а сюда относятся все операции с сетью), должны выполнятся в отдельном потоке. Android SDK предоставляет нам как минимум два варианта решения этого вопроса, один из которых (и на мой взгляд самый правильный) — это AsyncTask. Так, с этим понятно. Идем дальше.
Вторая и самая главная проблема — как вернуть результат работы с сетью в наш основной поток, что бы показать его на экране? Ну давайте разбираться… Что мы знаем про AsyncTask из того, что могло бы нам помочь? А знаем мы то, что его метод onPostExecute выполняется в основном потоке! Этот факт дает нам как минимум два варианта решения проблемы. Номер раз — мы попросту можем передать наш графический контроль (в моем случае это ListView) в AsyncTask параметром и заполнить его данными на onPostExecute. Этот вариант чаще всего встречается в интернете в качестве примера решения нашей задачи. И номер два — вариант который дает нам большую гибкость — это использование делегата. Тут конечно тоже есть несколько вариантов, но я рассмотрю только один из них, который мне больше всех нравится.
Пора переходить от слов к делу!
Итак, для начала мы создадим интерфейс в котором будет всего один метод:
public interface GetDataListener { void onGetDataComplete(JSONArray result); }
Теперь имплементируем этот интерфейс в нашу activity:
public class MyActivity extends Activity implements GetDataListener { private ListView list; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); list = (ListView) findViewById(R.id.lvData); } public void onGetDataComplete(JSONArray responce) { ... // заполняем данными наш ListView ... } }
Ну а теперь пришла пора AsyncTask:
public class GetData extends AsyncTask<Void, Void, JSONArray> { private final static String SERVICE_URI = "http://moi.service.com/service.php"; private GetDataListener listener; GetData(GetDataListener listener) { this.listener = listener; } protected void onPostExecute(JSONArray result) { listener.onGetDataComplete(result); } protected JSONArray doInBackground(Void... params) { return CallService(); } private JSONArray CallService() { JSONArray records = null; ... // забираем наши данные с вебсервиса ... return records; } }
Обратите внимание на конструктор! Тут мы получаем нашего делегата и сохраняем его.
Теперь все практически готово, осталось только запустить наш механизм из нашей activity:
new GetData(this).execute();
Как видите ничего революционного, чисто и просто. Надеюсь, что я кому-нибудь сэкономил время.
