Статьи

Залп, сетевая библиотека для Android

Эта статья была обновлена ​​21 декабря 2016 года. В частности: новая запись, обновленный устаревший код и добавлен новый раздел для загрузки изображений.

Сеть с Volley в Android

Сеть была вокруг с нулевого дня мобильных технологий, и Android не отличается. Изменился способ обработки сетевых операций. Центром сетевых библиотек, таких как Volley, была автоматизация сетевых операций.

До HoneyComb сетевые вызовы выполнялись из основного потока, а в последующих версиях Android сетевые запросы выполнялись асинхронно из основного потока. Чтобы выполнить сетевой вызов, разработчику необходимо внедрить Asynctask в другом потоке, отличном от основного потока приложения, NetworkOnMainThreadException будет NetworkOnMainThreadException .

Краткий обзор залпа

Volley — это сетевая библиотека для Android, которая управляет сетевыми запросами. Он объединяет самые важные функции, которые вам нужны, такие как доступ к API-интерфейсам JSON, загрузка изображений и запросов String в более простой в использовании пакет.

Используя Volley для сетевых операций, вы избегаете стандартного способа управления сетью, HttpURLConnection . Другая причина — асинхронность. Volley обрабатывает асинхронность сама по себе, нет необходимости создавать Asynctask вручную.

Основываясь на документации , ядром каждой сетевой операции, выполняемой Volley, является RequestQueue . Работа с Volley выполняется путем создания RequestQueue и передачи ему объектов Request . RequestQueue управляет рабочими потоками для выполнения сетевых операций, чтения и записи в кэш и анализа ответов.

Volley предлагает множество функций, как указано в его документации :

  1. Автоматическое планирование сетевых запросов.
  2. Несколько одновременных сетевых подключений.
  3. Кэширование.
  4. Запрос приоритизации.
  5. Отмена текущих запросов API.

Это основные преимущества, которые предоставляет эта библиотека, и основное внимание в этой статье.

Импортировать залп, добавить разрешения

Прежде чем начать работу с Volley, вам необходимо настроить проект Android.
Создайте новый проект Android. Откройте build.gradle(Module: app) и добавьте следующую зависимость.

 dependencies { //... compile 'com.android.volley:volley:1.0.0' } 

В AndroidManifest.xml добавьте интернет-разрешение.

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

Стандартные сетевые запросы

Как я упоминал ранее, ядром каждой сетевой операции, выполняемой Volley, является RequestQueue . Каждый запрос к сети передается в объекты RequestQueue через объекты Request .
Существует три типа запросов: запросы JSON, запросы изображений и запросы строк. Я рассмотрю каждый из этих типов с пояснениями и примерами кода.

На данный момент в MainActivity onCreate() RequestQueue инициируйте RequestQueue .

  RequestQueue requestQueue; @Override protected void onCreate (Bundle savedInstanceState) { //... requestQueue = Volley.newRequestQueue( this ); // 'this' is the Context } 

JSON Requests

У Volley есть Запросы для JSONObject и JSONArray . Структура JSONRequest и большинство классов запросов, включенных в Volley, используют конструкторы, подобные следующим.

 JsonObjectRequest request JsonObjectRequest(RequestMethod, URL, null , new ResponseListener(), new ErrorListener()); 

Параметры, передаваемые в конструктор:

  • RequestMethod (GET, POST, PUT, DELETE и т. Д.)
  • URL : строка URL требуемого объекта
  • JSONObject : необязательный объект, опубликованный с запросом, JSONObject , если объект не опубликован
  • ResponseListener : слушатель ответа, чей метод обратного вызова будет содержать ответ
  • ErrorListener : Response.ErrorListener , метод обратного вызова которого будет содержать любую проблему с запросом.

Следующие фрагменты кода являются полной реализацией JsonObjectRequest и JsonArrayRequest соответственно.

 /*Json Request*/ String url = "https://json_url/" ; JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null , new Response.Listener<JSONObject>() { @Override public void onResponse (JSONObject response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse (VolleyError error) { } }); //add request to queue requestQueue.add(jsonObjectRequest); JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null , new Response.Listener<JSONArray>() { @Override public void onResponse (JSONArray response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse (VolleyError error) { } }); //add request to queue requestQueue.add(jsonArrayRequest); 

Теперь, когда я показал, как получать данные JSON в Android, давайте посмотрим, как публиковать данные с помощью Volley.

Запрос имеет тот же формат, что и прием данных JSON, за исключением того, что вы должны указать JSONObject отправленный с запросом, и заголовки запроса для отправки данных от клиента на сторону сервера.

 /*Post data*/ Map<String, String> jsonParams = new HashMap<String, String>(); jsonParams.put( "email" , "[email protected]" ); jsonParams.put( "username" , "user" ); jsonParams.put( "password" , "pass" ); JsonObjectRequest postRequest = new JsonObjectRequest( Request.Method.POST, URL, new JSONObject(jsonParams), new Response.Listener<JSONObject>() { @Override public void onResponse (JSONObject response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse (VolleyError error) { // Handle Error } }) { @Override public Map<String, String> getHeaders () throws AuthFailureError { HashMap<String, String> headers = new HashMap<String, String>(); headers.put( "Content-Type" , "application/json; charset=utf-8" ); headers.put( "User-agent" , System.getProperty( "http.agent" )); return headers; } }; requestQueue.add(postRequest); 

Обратите внимание, что заголовки запроса могут изменяться в зависимости от варианта использования разработки.

Строка запроса

Этот тип запроса используется для извлечения данных с сервера в виде строки.

 /*String Request*/ String url = "https://string_url/" ; StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse (String response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse (VolleyError error) { } }); //add request to queue requestQueue.add(stringRequest); 

Структура StringRequest содержит метод запроса (POST или GET), URL-адрес источника String, Response.Listener и Response.ErrorListener . JsonRequest же, как JsonRequest .

Запрос изображения

Volley предлагает несколько способов загрузки изображений в Android. Я рассмотрю их все, чтобы объяснить их различия и привести некоторые примеры кода.

ImageRequest

ImageRequest — это способ загрузки изображений для получения изображения по заданному URL. Структура этого сетевого вызова аналогична другим ранее представленным запросам.
Следующий код является примером ImageRequest для загрузки изображения в ImageView .

 int maxWidth = ...; int maxHeight = ...; String URL = "http://image_url.png" ; ImageRequest imageRequest = new ImageRequest(URL, new Response.Listener<Bitmap>() { @Override public void onResponse (Bitmap response) { // Assign the response to an ImageView ImageView imageView = (ImageView) findViewById(R.id.imageView); imageView.setImageBitmap(response); } }, maxWidth, maxHeight, null ); //add request to queue requestQueue.add(imageRequest); 

Структура ImageRequest проста. Ему нужны URL-адрес изображения, прослушиватель ответа, метод обратного вызова которого будет содержать растровое изображение в качестве ответа, maxWidth и maxHeight , формат Config для декодирования растрового изображения и Response.ErrorListener для любых ошибок ответа. Добавьте запрос в RequestQueue а RequestQueue среда выполнения Android.

ImageLoader

ImageLoader — это вспомогательный класс для обработки загрузки и кэширования изображений с удаленных URL-адресов. Этот запрос полезен для большого количества ImageRequest . В соответствии с документацией ImageLoader предоставляет кэш в памяти перед обычным кешем Volley, что важно для предотвращения мерцания.

NetworkImageView

NetworkImageView — эффективный способ заменить ImageView когда изображения загружаются из сети.

Следующие фрагменты кода обеспечивают реализацию двух последних разделов загрузки изображений с помощью Volley. Следующий класс VolleySingleton является реализацией RequestQueue . Этот одноэлементный класс имеет возможности кэширования с LRU-кешем в памяти. LruCache настроен на хранение до 30 элементов.

 import android.content.Context; import android.graphics.Bitmap; import android.support.v4.util.LruCache; import android.util.Log; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.Volley; public class VolleySingleton { private static VolleySingleton singletonInstance = null ; private RequestQueue requestQueue; private ImageLoader imageLoader; private VolleySingleton (Context context) { requestQueue = Volley.newRequestQueue(context); imageLoader = new ImageLoader( this .requestQueue, new ImageLoader.ImageCache() { private final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>( 30 ); //30 -> the maximum number of entries in the cache. public void putBitmap (String url, Bitmap bitmap) { lruCache.put(url, bitmap); Log.d( "CachedItems" , String.valueOf(lruCache.size())); } public Bitmap getBitmap (String url) { return lruCache.get(url); } }); } public static VolleySingleton getInstance (Context context) { if (singletonInstance == null ) { singletonInstance = new VolleySingleton(context); } return singletonInstance; } public RequestQueue getRequestQueue () { return this .requestQueue; } public ImageLoader getImageLoader () { return this .imageLoader; } } 

Теперь, VolleySingleton класс VolleySingleton настроен, давайте загрузим изображение в NetworkImageView . Но сначала добавьте экземпляр в файл макета Activity. Вот пример:

 < com.android.volley.toolbox.NetworkImageView android:id = "@+id/networkImageView" android:layout_width = "match_parent" android:layout_height = "wrap_content" /> 

Наконец, загрузите изображение в NetworkImageView . В MainActivity onCreate() метода onCreate() добавьте этот код.

 private ImageLoader imageLoader; private NetworkImageView imageView; private static final String IMAGE_URL = "https://the_images_url.jpg" ; @Override protected void onCreate (Bundle savedInstanceState) { //... imageLoader = VolleySingleton.getInstance(getApplicationContext()).getImageLoader(); imageView = (NetworkImageView) findViewById(R.id.networkImageView); imageView.setImageUrl(IMAGE_URL, imageLoader); } 

Чтобы убедиться, что кеш работает правильно, я добавил оператор Log в класс VolleySingleton . Запустите проект и проверьте Вход в Android Studio. Каждый раз, когда новое изображение кэшируется, устройство печатает несколько кэшированных элементов.

Запрос приоритетов

Обработка сетевых запросов означает установление приоритетов в отношении того, что необходимо и насколько быстро требуется ответ, поскольку работа в сети является операцией в реальном времени.

Volley обрабатывает запросы от более высоких приоритетов к более низким приоритетам, в порядке очереди. Метод setPriority() , поэтому для определения приоритета запроса требуется некоторая работа.

Вот пример пользовательского класса JsonObjectRequest который может делать приоритетные запросы. Основное внимание в этом классе уделяется переопределенному getPriority() . Когда запрос добавляется в очередь, этот метод возвращает приоритет, назначенный ему setPriority() , или возвращает Priority.HIGH назначенный внутри класса, но он не будет искать приоритет вне этого класса.

Та же самая структура применяется ко всем другим типам запросов.

 public class CustomPriorityRequest extends JsonObjectRequest { Priority priority = Priority.HIGH; public CustomPriorityRequest ( int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super (method, url, jsonRequest, listener, errorListener); } public CustomPriorityRequest (String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super (url, jsonRequest, listener, errorListener); } @Override public Priority getPriority () { return priority; } public void setPriority (Priority p){ priority = p; } } 

Создание запроса с этим новым классом аналогично стандартным запросам. У вас есть возможность установить приоритет запроса перед добавлением его в очередь.

  CustomPriorityRequest customPriorityRequest = new CustomPriorityRequest( Request.Method.GET, URL, null , new Response.Listener<JSONObject>(), new Response.ErrorListener()); customPriorityRequest.setPriority(Request.Priority.IMMEDIATE); requestQueue.add(customPriorityRequest); 

Некоторые доступные приоритеты: Приоритет. НИЗКИЙ, Приоритет. НОРМАЛЬНЫЙ, Приоритет. ВЫСОКИЙ и Приоритет. НЕМЕДЛЕННЫЙ.

Отмена запросов

Еще одним полезным инструментом в Volley является возможность отмены запросов. Отмена запросов полезна, когда пользователь закрывает приложение или выполняет действие, в результате которого не используются ответы на запросы залпа. Нет смысла выполнять оставшиеся запросы в очереди, поэтому мы отменяем их в onStop() .

Самый простой способ отменить запросы в Volley — это добавить тег к запросу, а когда запросы в очереди нужно отменить, вызовите метод cancelAll() . Это отменит все запросы, указанные с этим конкретным тегом.

 request.setTag( "TAG" ); requestQueue.cancelAll( "TAG" ); 

Как только cancelAll() выполняется из основного потока, остальные ответы не будут доставлены.