Различные способы дебага запросов с Android-устройств и эмуляторов
Многие разработчики сталкиваются с вопросом: «Как посмотреть то, что приложение отправляет в сеть и как увидеть ответ от сервера?». Существует множество различных вариантов профайлинга, но описать все будет довольно проблематично. Для себя я выделил 5 способов, которыми и поделюсь с вами:
- Android Studio Profiler (Network) — нативный профайлер Android Studio;
 - OkHttp Profiler — плагин для Android Studio/IntelliJ IDEA;
 - Facebook Stetho — «мост» между приложением и дебаггером браузера;
 - Charles — прокси-приложение для работы с сетью;
 - AppSpector — библиотека удаленного профайлинга.
 
Все они имеют свои плюсы и минусы, но однозначно позволят вам сделать профайлинг работы с сетью удобным и прозрачным.
Android Profiler
С каждым годом разработчики Android и Android Studio делают жизнь программистов все проще и проще. В студии 3.0 был добавлен отличный функционал — Advanced Network Profiling. Он может отобразить количество отправленных/полученных данных, тайминг сети, а главное, с помощью него вы можете увидеть запросы непосредственно в Android Studio.
Правда, есть некие ограничения — поддержка только HttpURLConnection или OkHttp, но, думаю, этого достаточно с головой.
Итак, для включения расширенного профайлинга:
1. Надо зайти в меню Run > Edit Configurations.

2. Выбрать свой модуль в левой части.
3. Перейти в Profiling вкладку в правой части и включить Enable advanced profiling.
4. И теперь скомпилировать и запустить проект.
Затем открываем Profiler и выбираем Network. После этих манипуляций видим запросы в реальном времени, и если выделим какой-то временной интервал, то отобразится детальная информация:

Всю эту нехитрую настройку и использование вы можете просмотреть на видео.
Из плюсов такого метода я могу выделить следующие:
- нативная реализация от Google;
 - можно смотреть и картинки и «текстовые» ответы;
 - есть тайминги, что очень важно для анализа быстродействия.
 
Из минусов:
- постоянно надо выделять участок времени — нет общего списка запросов;
 - надо держать активной сессию профайлера;
 - нет отображения JSON в виде дерева.
 
OkHttp Profiler plugin
Плагин к Android Studio/Intellij IDEA, который отображает запросы библиотек OkHttp/Retrofit непосредственно в IDE. У него встроена возможность создания Java/Kotlin моделей для Gson десериализатора из полученного JSON-ответа.

Для активизации плагина необходимо добавить Interceptor-библиотеку в build.gradle файл (на уровень модуля):
dependencies {
    //……………
    implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.3'
}
И подключить ее к OkHttp-клиенту:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
    builder.addInterceptor(new OkHttpProfilerInterceptor());
}
OkHttpClient client = builder.build();
Выключаем по умолчанию лишние обработчики для релизных билдов — они там ни к чему. Далее устанавливаем сам плагин, вызывая меню настроек:
Preferences -> вкладка Plugins -> жмем на кнопку Browse repositories... -> и вводим OkHttp Profiler.
В списке отобразится плагин последней версии, нажимаем Install и Restart.
Внизу справа появился «OkHttp Profiler» — открываем его и пересобираем проект. Теперь все исходящие запросы будут отображаться в этом окне.
Небольшое демо использования. Дополнительная информация о установке здесь.
Из плюсов этой библиотеки могу отметить такие:
- есть полный список запросов, отсортированный по дате отправки;
 - возможность просмотреть JSON в удобном виде — текстовом или дерево;
 - возможность в один клик создать Java/Kotlin модель для Gson-парсера прямо из ответа сервера.
 
Из минусов:
- необходимость добавления сторонней библиотеки;
 - есть небольшие задержки отображения контента запроса.
 
Stetho
Профайл-решение от компании Facebook, которое придется по душе тем, кто уже дебажил веб в браузере Chrome. Эта библиотека создает некий мост между вашим приложением и браузером, с помощью которого отображаются данные по сети, базе данных и view иерархии.
Для включения надо добавить саму библиотеку в build.gradle:
  dependencies { 
    implementation 'com.facebook.stetho:stetho:1.5.0' 
    implementation 'com.facebook.stetho:stetho-okhttp3:1.5.0'  // если вы используете OkHttp 
  } 
И инициализировать ее в onCreate методе MainActivity:
class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Stetho.initializeWithDefaults(this);
    }    
}
Для OkHttp-клиента надо добавить interceptor при инициализации:
new OkHttpClient.Builder()
    .addNetworkInterceptor(new StethoInterceptor())
    .build();
Запускаем приложение со всеми изменениями, открываем Chrome-браузер и вбиваем в строку адреса chrome://inspect/#devices.
Нажимаем «Inspect» возле приложения.

Во вкладке Network будет будут появляться все исходящие запросы.

Из плюсов могу отметить:
- если вы пользовались дебагом в Chrome ранее, этот способ будет вам удобен;
 - помимо нетворкинга вы можете видеть базу данных и layout приложения;
 - довольно-таки простое подключение.
 
Из минусов:
- необходимость подключения сторонней библиотеки;
 - окно профайлера находится отдельно от студии.
 
Charles Proxy
Прокси-приложение, которое отображает весь исходящий и входящий трафик с устройства. Оно также содержит много инструментов для работы с сетью: составление новых запросов, переадресация, изменение параметров сети (имитация плохой связи), отображение подключенных сокетов. Приложение платное, но его можно использовать без покупки (будет требовать перезагрузку через какой-то интервал времени).
Для направления всего трафика через Charles необходимо настроить и устройство, и сам проект. Рассмотрим на примере нативного эмулятора с Android 8.0 на борту.
Качаем приложение по ссылке (есть версии для Windows, Mac, Linux).
Открываем настройки эмулятора:
Preferences -> Network & Internet -> Wi-fi -> Edit -> Settings icon

И вводим:
Proxy: Manual
Proxy hostname: 10.0.2.2 (это не локальный IP, просто всегда используйте 10.0.2.2)
Proxy port: 8888
Нажимаем Save.
Теперь нужно установить сертификат безопасности, дабы мы могли видеть HTTPS-запросы.
Возвращаемся на главный экран эмулятора и вводим chls.pro/ssl в строку поиска. Эмулятор сохранит файл, открываем его (или нажав на push notification или просто в папке Downloads). Система попросит ввести имя сертификата — туда вбиваем любое значение (имя не влияет ни на что). Затем будет предложено обезопасить систему, выбираем простой пин и устанавливаем что-то типа 1111 — это тоже не имеет значения.

И это еще не конец :)
Далее нам надо разрешить приложению использовать пользовательские сертификаты, но делаем это только для debug-билдов. Для чего нам это делать, вы можете прочитать здесь.
Открываем наш проект и в папке ресурсов (res) создаем папку xml, в ней уже создаем файл network_security_config.xml.
И добавляем туда строки:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<debug-overrides>
    <trust-anchors>
        <certificates src="/system" />
        <certificates src="/user" />
    </trust-anchors>
</debug-overrides>
</network-security-config>
В итоге мы получим следующую картину:

Затем добавим настройку в AndroidManifest.xml, открываем его и добавляем android:networkSecurityConfig="@xml/network_security_config" в application tag.

И это еще тоже не все :)
Открываем Charles, меню Proxy -> SSL Proxing Settings...
Во всплывшем окне ставим галочку в чекбокс Enable SSL Proxying и добавляем домены, с которыми будет работать наше приложение.
 
Теперь пересобираем наш проект и смотрим результаты в Charles.
 
Из плюсов такого способа:
- удобное отображение запроса и ответа;
 - есть возможность менять параметры сети;
 - любой запрос можно повторить/редактировать;
 - возможность работать с сокетами.
 
Из минусов:
- не самая простая установка;
 - 1 лицензия на Charles стоит $50;
 - необходимость включения/выключения прокси на устройстве (если включить — то без Charles сеть не работает);
 - профайлинг отдельно от Android Studio.
 
AppSpector
Решение для профайлинга сети и не только. Через него можно посмотреть базу данных, логи, системную информацию.
Для подключения необходимо зарегистрироваться на сервисе.
После регистрации вам будут показаны актуальные коды подключения с нужным ключом.
Надо добавить следующее в build.gradle проекта:
buildscript {
  repositories {
      jcenter()
      google()
      maven {
          url "https://maven.appspector.com/artifactory/android-sdk"
      }
  }
  
  dependencies {
      classpath "com.appspector:android-sdk-plugin:1.0.4"
  }
}
apply plugin: 'com.android.application'
И в build.gradle модуля:
// Put AppSpector plugin after Android plugin
apply plugin: 'com.appspector.sdk'
repositories {
    maven {
        url "https://maven.appspector.com/artifactory/android-sdk"
    }
}
dependencies {
    implementation "com.appspector:android-sdk:1.0.4"
}
Затем добавить инструмент в Application:
import android.app.Application;
import com.appspector.sdk.AppSpector;
public class AmazingApp extends Application {
   @Override
   public void onCreate() {
      super.onCreate();
      
      // We recommend to start AppSpector from Application#onCreate method
      
      // You can start all monitors
      AppSpector
            .build(this)
            .withDefaultMonitors()            
            .run("YOUR_CODE");
}
}
После запуска проекта с этими изменениями в кабинете пользователя появится каждый девайс, на котором запустили приложение.

Выбрав устройство, видим различные области профайлинга, в том числе и сеть.

Итак, плюсы:
- есть постоянно хранящийся список отправленных/полученных данных;
 - запрос можно посмотреть в удобном виде;
 - возможность профайлинга базы, логов т. д.
 
Минусы:
- много зависимостей при подключении;
 - уходит вся информация с устройства (все логи, запросы, ответы, база данных) и хранится на стороннем сервисе в сети, что немного небезопасно;
 - профайлинг отдельно от Android Studio;
 - сейчас AppSpector в бете, и он бесплатный. Но анонсировано, что в октябре 2018 появятся цены за использование (сейчас уже и ноябрь, но их пока нет).
 
Вывод
Плюсы и минусы основаны исключительно на моих соображениях, так что они субъективны и могут отличаться от ваших. Если вы знаете, используете еще какие-то способы, которые удобны и доступны — милости прошу оставить комментарий под текстом :)
Всем добра.