Как добавить Apache HTTP API (устаревший) в качестве зависимости времени компиляции для build.grade для Android M?


96

Как упоминалось здесь , Android M не будет поддерживать Apache HTTP API. В документации говорится:

вместо этого используйте класс HttpURLConnection.

или

Чтобы продолжить использование API-интерфейсов Apache HTTP, сначала необходимо объявить следующую зависимость времени компиляции в файле build.gradle:

android {useLibrary 'org.apache.http.legacy'}

Я преобразовал большую часть использования HttpClient в моем проекте в HttpURLConnection, однако мне все еще нужно использовать HttpClient в некоторых областях. Следовательно, я пытаюсь объявить org.apache.http.legacy как зависимость времени компиляции, но получаю сообщение об ошибке в build.gradle:

Метод Gradle DSL не найден: 'useLibrary ()'

Мой вопрос: как мне объявить org.apache.http.legacy как зависимость времени компиляции в моем проекте?

Любая помощь очень ценится. Спасибо


3
Убедитесь, что вы используете достаточно свежий плагин Gradle для Android. Я предполагаю, что это действительно новинка, то есть вам понадобится что-то вроде 1.3.0-rc2. Вы также можете рассмотреть возможность использования собственного Android-совместимого выпуска Apache HttpClient .
CommonsWare

Спасибо за быстрый ответ @CommonsWare ... Вы имеете в виду строку "classpath 'com.android.tools.build:gradle:1.0.0' в файле build.gradle верхнего уровня?
Вират Сингх

1
Да. Я буду очень удивлен, если 1.0.0у меня будет такая useLibraryвещь. Возможно, он закрался до 1.3.x, поэтому вы можете попробовать 1.2.3(AFAIK, последний производственный выпуск) и посмотреть, что произойдет.
CommonsWare

Я просто попробовал '1.2.3' и не повезло - та же ошибка -> «Метод Gradle DSL не найден: 'useLibrary ()'»: /
Вират Сингх

Да, поскольку это связано с M Developer Preview, я не шокирован этим. Наверное вам нужно 1.3.0-rc2(или что-то новее, если есть).
CommonsWare

Ответы:


172

Для API 23:

Build.gradle верхнего уровня - /build.gradle

buildscript {
    ...
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.1'
    }
}
...

Специфичный для модуля build.gradle - /app/build.gradle

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.0"
    useLibrary 'org.apache.http.legacy'
    ...
}

Официальные документы (для предварительного просмотра): http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client

Последний журнал изменений плагина Android Gradle: http://tools.android.com/tech-docs/new-build-system


2
Я обновляю версию сборки gradle, а затем объявляю useLibrary для apache, но также получаю сообщение об ошибке: Ошибка: (204, 13) ошибка: не удается найти класс символов DefaultHttpClient Ошибка: (204, 48) ошибка: не удается найти класс символов DefaultHttpClient Ошибка: (205, 13) ошибка: не удается найти класс символа HttpPost Ошибка: (205, 37) ошибка: не удается найти класс символа HttpPost Ошибка: (207, 13) ошибка: не удается найти класс символа HttpResponse Ошибка: (208, 13) ошибка: невозможно найти класс символа HttpEntity Ошибка: (209, 19) ошибка: не удается найти символьную переменную EntityUtils
Варнит Ханделвал

1
Что-то, что я пропустил из ответа: вам нужно убедиться, что путь к классам gradle находится в файле сборки верхнего уровня вашего приложения, где он useLibraryдолжен быть в файле сборки вашего приложения.
Грэм

Также не забудьте добавить этот jar- файл, чтобы вышеуказанное решение работало :)
Шераз Ахмад Хилджи

@Sheraz, который больше не требуется - сборка gradle поднимает его автоматически
Ричард Ле Мезурье

1
@Ratul, вы должны добавить packagingOptions {}блок внутри androidблока, внутри этого блока добавить exclude 'META-INF/LICENSE'... (сообщается каждая строка для каждого файла-дубликата)
hidro

28

Другая альтернатива - просто добавить зависимость jbundle. Это больше подходит для Android Studio, поскольку Android Studio не выдает сообщение «не удается разрешить символ ...»

 dependencies {
    compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
 }

он доступен в репозитории mavenCentral ().
nexDev

Не может быть скомпилирован: Ошибка: Выполнение не выполнено для задачи ': <Proj>: package <Proj> Debug'. > Невозможно вычислить хэш /Users/<user>/Documents/<Proj>/<Activity>/build/intermediates/classes-proguard/<Proj>/debug/classes.jar
Юрий Чернышов

вы пробовали компилировать (пересобирать) без прогарда?
nexDev

не могли бы вы показать образец проекта, который работает с этим? Теперь я получаю эту ошибку: Ошибка: Выполнение не удалось для задачи ': app: packageAllSyncmeappDebugClassesForMultiDex'. > java.util.zip.ZipException: повторяющаяся запись: org / apache / http / annotation / GuardedBy.class
разработчик Android

Что ж, тип ошибки, который у вас есть, кажется специфичным для вашего проекта. У вас есть дубликаты пакетов apache. Очевидно, один в org.jbundle. .... а другой где-нибудь в одной из ваших библиотек. Я бы
поискал


13

В вашем файле build.gradle добавьте useLibrary 'org.apache.http.legacy' в соответствии с Android 6.0 Changes> Apache HTTP Client Removalпримечаниями.

android {
    ...
    useLibrary 'org.apache.http.legacy'
    ...
}

Чтобы избежать ошибок отсутствия ссылок, добавьте в зависимости

dependencies {
    provided 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
}

при использовании 'при условии' зависимость не будет включена в apk


11

Только что скопированный файл: org.apache.http.legacy.jarиз Android/Sdk/platforms/android-23/optionalпапки в папку проекта app/libs.

Сработал шарм на 23.1.1.


2

Я решил эту проблему так:

1.) Установите путь к классам в файле сборки верхнего уровня, как указано в GUG:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0-beta2'
    }
    allprojects {
        repositories {
           jcenter()
        }
    }
}

2.) В файле сборки конкретного модуля:

android {
   useLibrary 'org.apache.http.legacy'
   compileSdkVersion 'android-MNC'
   buildToolsVersion '23.0.0 rc3'
}

2

Поскольку ответы немного устарели, я поставлю свое решение (которое сработало для меня), оно может быть полезно для кого-то еще ... Я взял свое решение из официальной документации Apache, без обходного пути.

1 / в градле:

dependencies {
...
// This is the maintained version from apache.
compile group: 'cz.msebera.android', name: 'httpclient', version: '4.4.1.1'
}

2 / в остальной части приложения замените на org.apache.http, cz.msebera.android.httpclientи весь ваш импорт (зависимости) будет исправлен. вы можете просто нажать ctrl + shift + R и заменить его во всем проекте.


2

это должно помочь:

android {
    ...
    useLibrary 'org.apache.http.legacy'
    ...
}

Чтобы избежать ошибок отсутствия ссылок, добавьте в зависимости

dependencies {
    provided 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
}

или

dependencies {
    compileOnly 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
}

так как

Warning: Configuration 'provided' is obsolete and has been replaced with 'compileOnly'.

или дайте compile вместо при условии, что оба будут работать
logeshwaran

с приведенной выше конфигурацией я столкнулся с ошибкой: (155, 0) Метод Gradle DSL не найден: 'provided ()'
RoFF

1

FWIW удаление библиотеки Apache было предсказано некоторое время назад. Наш хороший друг Джесси Уилсон дал нам подсказку еще в 2011 году: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

Google прекратил работу над ApacheHTTPClient некоторое время назад, поэтому любую библиотеку, которая до сих пор полагается на нее, следует включить в список устаревших библиотек, если сопровождающие не обновят свой код.

<rant> Я не могу сказать вам, сколько технических споров у меня было с людьми, которые настаивали на использовании HTTP-клиента Apache. Есть несколько крупных приложений, которые могут сломаться, потому что руководство моих предыдущих работодателей, которые я не называю, не слушало своих ведущих инженеров или не знало, о чем они говорили, когда игнорировало предупреждение ... мост.

Я выигрываю.

</rant>


1
Насколько я понимаю, Apache HttpClient - это скрыт в android-23, но фактически не удален. Удаление приведет к поломке многих существующих клиентов, ориентированных на более ранние платформы, где HttpClient не скрыт, и ожидается, что эти существующие приложения по-прежнему будут работать на android-23. В android-23 добавление useLibrary служит для добавления этих устаревших классов в путь к загрузочным классам, то есть в список классов, предоставляемых платформой. По сути, это показывает классы на android-23.
Джо Баубир,

Когда класс устарел, его обычно сначала скрывают, чтобы предотвратить его дальнейшее использование. Потом его можно будет удалить со временем. Что-то вроде: 1. Отметить как устаревшее в текущей версии. 2. Скрыть во второй версии. 3. проведите рефакторинг всего кода, чтобы полностью удалить старый класс.
Coder Roadie

0

Чтобы решить эту проблему, убедитесь, что вы используете инструменты сборки версии "23.0.0 rc2" со следующими инструментами построения зависимостей Gradle:

classpath 'com.android.tools.build:gradle:1.3.0-beta2'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.