Какая разница между Android Html.escapeHtml и TextUtils.htmlEncode? Когда следует использовать один или другой?

Android имеет два разных способа избежать/кодировать HTML-символы/сущности в строках:

  • Html.escapeHtml(String), добавленный в API 16 (Android 4.1). Документы говорят:

    Возвращает HTML-экранированное представление данного открытого текста.

  • TextUtils.htmlEncode(String) В этом документе говорится:

    Html-кодирует строку.

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

Eg. При вводе: <p>This is a quote ". This is a euro symbol: €. <b>This is some bold text</b></p>

  • Html.escapeHtml дает:

    &lt;p&gt;This is a quote ". This is a euro symbol: &#8364;. &lt;b&gt;This is some bold text&lt;/b&gt;&lt;/p&gt;
    
  • В то время как TextUtils.htmlEncode дает:

    &lt;p&gt;This is a quote &quot;. This is a euro symbol: €. &lt;b&gt;This is some bold text&lt;/b&gt;&lt;/p&gt;
    

Таким образом, кажется, что второй ускоряет/кодирует цитату ("), но первая не делает, хотя первая кодирует символ Евро, а вторая - нет. запутался.


Итак, какая разница между этими двумя методами? Какими персонажами каждый побег/кодирование? Какая разница между кодированием и экранированием здесь? Когда я должен использовать один или другой (или мне, вздохнуть, использовать их вместе?)?

Ответ 1

Вы можете сравнить их источники:

Это то, что Html.escapeHtml использует под:

https://github.com/android/platform_frameworks_base/blob/d59921149bb5948ffbcb9a9e832e9ac1538e05a0/core/java/android/text/Html.java#L387

Это TextUtils.htmlEncode:

https://github.com/android/platform_frameworks_base/blob/d59921149bb5948ffbcb9a9e832e9ac1538e05a0/core/java/android/text/TextUtils.java#L1361

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

Таким образом, если ваш ввод содержит только латинские символы (что обычно маловероятно в наши дни), или вы правильно настроили Unicode на своей HTML-странице и можете идти вместе с TextUtils.htmlEncode. Если вам нужно убедиться, что ваш текст работает, даже если он передается через 7-битные каналы, используйте Html.escapeHtml.

Что касается различной трактовки символа кавычки ("), то его нужно избегать внутри значений атрибутов (см. спецификацию), поэтому, если вы не помещаете текст там, вы должны быть в порядке.

Таким образом, мой личный выбор был бы Html.escapeHtml, поскольку он кажется более универсальным.