Статьи

Ожидание Android: UrlJsonAsyncTask

Ожидание Android: UrlJsonAsyncTask

  • Исходный код для этой статьи: UrlJsonAsyncTaskTest на GitHub
  • Загрузите и установите приложение для Android: UrlJsonAsyncTaskTest.apk (Android 2.2 или более поздняя версия )
  • Вы также можете отсканировать этот QR-код, чтобы загрузить его на свой телефон Android:

QR-код UrlJsonAsyncTaskTest

обзор

Я даже не могу сосчитать, сколько раз мне приходилось загружать ProgressDialog в Android, запрашивать JSON с удаленного URL-адреса, а затем возвращать управление обратно в приложение после завершения запроса. Это невероятно распространенный поток управления, и мне надоело снова и снова. Я уверен, что я не одинок.

Чтобы сохранить эту СУХУЮ ситуацию, класс UrlJsonAsyncTask в моей коллекции помощников Android, com.savagelook.android , посвящен вышеупомянутой задаче. Это сокращает то, что может быть более 80 строк кода для каждой задачи, до 15 или менее.

Прежде чем копаться, вот несколько вещей, чтобы рассмотреть.

  • Это не базовое руководство, поэтому предполагается, что вы знакомы с Android. В частности, вы должны понимать, как Android использует Intents, Activity и базовую обработку событий.
  • Хотя в этом нет необходимости, вам будет все легче понять, если вы хотя бы знакомы с классом Android AsyncTask .
  • Я использую несколько других классов в com.savagelook.android в UrlJsonAsyncTask которые вы, скорее всего, не узнаете, например JsonHelper и Lazy.Ex. Все они с открытым исходным кодом и свободно доступны на GitHub.
  • Я не понимаю, как работает UrlJsonAsyncTask , а как его использовать. Будьте услышаны в комментариях, если хотите, чтобы я продолжил.

UrlJsonAsyncTaskTest

Лучший способ узнать, как UrlJsonAsyncTask может ускорить вашу разработку, — увидеть ее в действии. Вы можете следовать приведенным ниже фрагментам кода или полностью раскрыть исходный код проекта, на котором я их основываю. Проект UrlJsonAsyncTaskTest, его можно бесплатно загрузить или клонировать с GitHub.

Приложение специально сделано как можно голее. Мы просто собираемся создать кнопку в нашем основном UrlJsonAsyncTask , которая запустит UrlJsonAsyncTask а затем вернет результат своего запроса в новом UrlJsonAsyncTask .

Прежде чем мы перейдем к Кодексу …

UrlJsonAsyncTask делает только одно предположение «соглашение о конфигурации». Для того чтобы все функции обработки ошибок и тайм-аута обрабатывались под капотом, ваш JSON должен быть в следующем формате:

 { "success": true|false, "info": "an error message to present to the user when success is false", "data": YOUR_DATA } 
  • success — это логическое значение, указывающее, был ли запрос успешным на стороне сервера.
  • info дает пользователю описательное, но очищенное описание ошибки.
  • data — это фактические данные, которые вы хотите вернуть из запроса. YOUR_DATA может быть любым значением или даже другим объектом или массивом JSON.

(Скучный) код

Хорошо, давайте сначала уберем скучные вещи. Вот изменения, которые необходимо внести в основной проект Android, чтобы он выглядел как UrlJsonAsyncTaskTest , если вам было лень скачивать / клонировать его самостоятельно.

AndroidManifest.xml

Вам нужно добавить 2 вещи. Во-первых, разрешите Android общаться с Интернетом, добавив условие uses-permission в элементе manifest.

 <uses-permission android:name="android.permission.INTERNET" /> 

Во-вторых, вам нужно добавить второе действие, которое мы откроем после успешного вызова UrlJsonAsyncTask в элементе application . Он будет соответствующим образом назван SecondActivity .

 <activity android:name=".SecondActivity"/> 

разреш / макет / main.xml

Это макет XML, который мы применим к MainActivity . Вот кнопка, которую мы будем использовать для запуска UrlJsonAsyncTask .

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/mainButton" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="Get Remote JSON"/> </LinearLayout> 

разреш / макет / second.xml

Это макет XML для SecondActivity . Здесь в TextView мы разместим строку JSON, которая возвращается из нашего вызова UrlJsonAsyncTask .

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/jsonText" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout> 

(Интересный) код

Теперь пришло время фактически расширить, создать экземпляр и вызвать нашу UrlJsonAsyncTask . Мы сделаем все это в MainActivity всего за несколько строк кода. Если вас не интересует весь пример проекта UrlJsonAsyncTaskTest, и вы просто хотите знать, как использовать UrlJsonAsyncTask в ваших собственных проектах, это раздел, на который вам нужно обратить внимание .

MainActivity.java

Первое, что нам нужно сделать, это создать наш собственный класс, который расширяет UrlJsonAsyncTask . Это позволит нам использовать встроенную функциональность, предоставляя нам свободу определять, как обрабатывается полученный JSON. Мы делаем это как private class член private class MainActivity . Прочитайте комментарии для деталей в каждом разделе.

 private class MyTask extends UrlJsonAsyncTask { // Create a default constructor public MyTask(Context context) { super(context); } // onPostExecute(JSONObject) is what is called when the UrlJsonAsyncTask completes. // The JSONObject represents the JSON returned by the remote URL we queried. @Override protected void onPostExecute(JSONObject json) { try { // call validateJson() to ensure well formatted JSON this.validateJson(json); // If the JSON is returned successfully and well formatted, send the // JSON "data" as String Extra "json" to SecondActivity Intent intent = new Intent(context, SecondActivity.class); intent.putExtra("json", json.getString("data").toString()); startActivity(intent); } catch (JSONException e) { // If there were exceptions handling the JSON... Toast.makeText(context, this.getMessageError(), Toast.LENGTH_SHORT).show(); } catch (Exception e) { // All other uncaught exceptions, like HTTP or IO problems... Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); } finally { // You MUST call this or your UrlJsonAsyncTask's ProgressDialog will // not close. super.onPostExecute(json); } } } 

Теперь, когда мы создали MyTask , все, что нам нужно сделать, это создать его экземпляр, дать ему (удаленный) URL-адрес и позволить основному UrlJsonAsyncTask выполнить остальную часть работы. Чтобы сделать его интерактивным, мы сделаем все это в обработчике mainButton кнопки mainButton в функции onCreate () MainActivity .

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button)findViewById(R.id.mainButton); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // The URL that'll we'll test against String remoteJsonUrl = "http://savagelook.com/misc/UrlJsonAsyncTaskTest.php"; // assign a context and loading message MyTask task = new MyTask(MainActivity.this); task.setMessageLoading("Getting remote JSON..."); // Launch the UrlJsonAsyncTask with the test URL task.execute(remoteJsonUrl); } }); } 

Если все идет хорошо, MyTask.onPostExecute() будет вызван, как только эта задача вернет запрошенный JSON из http://savagelook.com/misc/UrlJsonAsyncTaskTest.php .

SecondActivity.java

Просто чтобы убедиться, что все идет по плану, мы отобразим строку данных JSON в SecondActivity . Для этого мы добавим следующие несколько строк кода в SecondActivity.onCreate() .

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second); // Get the JSON string we assigned to the intent in MyTask.onPostExecute() String jsonString = this.getIntent().getStringExtra("json"); // assign the JSON string to the TextView TextView textView = (TextView)findViewById(R.id.jsonText); textView.setText(jsonString); } 

Вот и все. Теперь у вас должен быть UrlJsonAsyncTask, успешно подключающийся к удаленному URL-адресу и запрашивающий JSON, в то время как наличие ProgressDialog позволяет пользователю знать, что происходит. Как я уже говорил ранее, это очень распространенная задача, а теперь очень простая.

Резюме

В конце концов, мы достигаем не ракетостроения. Все, что мы делаем, это создаем типичный поток управления для приложения, которое опирается на удаленные данные. Моя цель состояла в том, чтобы сделать этот поток как можно более простым, не жертвуя слишком большой гибкостью.

Я настоятельно рекомендую вам проверить репозиторий GitHub для всего моего кода com.savagelook.android . Получить под капотом и посмотреть, как именно UrlJsonAsyncTask делает то, что он делает. Попробуйте некоторые другие свойства класса, такие как время ожидания и повторные попытки. Взгляните и на другие вспомогательные классы. Кроме того, не стесняйтесь клонировать и внести свой вклад обратно.

Надеемся, что это поможет вам тратить меньше времени на управление и больше времени на уникальную функциональность, предоставляемую вашими приложениями для Android.