Использование библиотеки Retrofit в проектах на Андроид

04.11.19

Разработка - Мобильная разработка

Использование библиотеки Retrofit в проектах на Андроид для обмена данными с 1С с помощью HTTP-сервисов, с примерами и готовым рабочим шаблоном.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Рабочий проект с примером работы с Retrofit и WorkManager
.7z 7,94Mb ver:1.1
13
13 Скачать (5 SM) Купить за 3 050 руб.

Решил вот написать статью. Так как писать статьи я не умею, прошу сильно не пинать за возможные ошибки.
Написать статью меня сподвигла вот эта вот публикация
//infostart.ru/public/463387/

В свое время для одного своего проекта на Андроид на базе этой публикации я делал обмен с 1С через WEB-Сервисы. Так как я был начинающим программистом на Андроид, алгоритм получился немного громоздким, т.к. в результате обмена я получал xml файл, который, в итоге,  надо было еще парсить средствами Андроид. Что-то типа вроде этого.

       try {
            XmlPullParser xpp = prepareXpp();
            while ((xpp.getEventType() != XmlPullParser.END_DOCUMENT)) {
                switch (xpp.getEventType()) {
                    case XmlPullParser.START_DOCUMENT:
//                        Log.d(LOG_TAG, "XmlPullParser.START_DOCUMENT Start document");
                        break;
                    case XmlPullParser.START_TAG:
  //                      Log.d(LOG_TAG, "XmlPullParser.START_TAG " + xpp.getName() + " " + xpp.getDepth());
                        switch (xpp.getDepth()) {
                            case 2:
                                data = new Bundle();
                                break;
                            case 3:
                                tagName = xpp.getName();
                        }

//                        if (xpp.getName().equals(XML_NODE_NAME_CONTACT)) {
//                            data = new Bundle();
//                        } else {
//                            tagName = xpp.getName();
//                        }
                        break;
                    case XmlPullParser.END_TAG:
//                        Log.d(LOG_TAG, "XmlPullParser.END_TAG " + xpp.getName());
                        tagName = "";
                        if (xpp.getDepth() == 2) {
                            addDataContact(data);
  //                          Log.d(LOG_TAG,data.get("FullName").toString());
    //                        Log.d(LOG_TAG,"ADD DATA");
                            //breakProgram = true;
                        }
                        break;
                    case XmlPullParser.TEXT:
      //                  Log.d(LOG_TAG, "XmlPullParser.TEXT "  + xpp.getText());
                        if (xpp.getDepth() == 3) {
                            String dataText = xpp.getText();
                            if (dataText == null) {
                                dataText = "";
                            };
                            data.putString(tagName, dataText);
                        }
//                        if (!tagName.isEmpty()) {
//                          data.putString(tagName, xpp.getText());
//                        }
                        break;
                    default:
                        break;

                }
                //if (breakProgram) break;
                xpp.next();
            }
        }catch (XmlPullParserException e) {
            //e.printStackTrace();
            DataXML.append(e.toString());
            sendMessage(MainActivity.STATUS_ERR);
            return "false";

//            Log.d(LOG_TAG, e.toString());
        }catch (Exception e) {
            //e.printStackTrace();
            DataXML.append(e.toString());
            sendMessage(MainActivity.STATUS_ERR);

//            Log.d(LOG_TAG, e.toString());
            return "false";
        }
     return "true";
    }

Да и тестирование WEB-сервиса тоже требовало определенных усилий и дополнительного софта. Библиотека ksoap, с помощью которой можно работать с WEB-Сервисами, не внушала у меня особого доверия, может я в ней не разобрался тогда до конца, может еще были причины. В общем, для меня все это было громоздким и устаревшим.

К тому же злые языки в 1С утверждали, что WEB-Сервисы - это вчерашний день и настоятельно рекомендовали переходить на HTTP-сервисы. И я не мог с ними не согласиться. И начал искать альтернативу. В поисках альтернативы наткнулся на библиотеку под названием Retrofit. Это HTTP клиент реализующий REST архитектуру. Выражаясь просто, ее можно использовать для обмена с 1С с помощью HTTP-сервисов. В дополнении к этому, эта библиотека умеет работать с json, но самое важное, что при работе с ней, программист оперирует классами (моделью). Т.е. получая результат от сервера, я работаю не с сырыми данными в виде xml или json, а уже готовыми классами.

Как это работает?

Например, у нас есть некоторые данные, которые надо получить из 1С. Средствами 1С легко получить данные в формате json. Создаем на стороне 1С HTTP-сервис, который принимает запрос и возвращает результат в виде json.

 

 

Функция ПолучитьПередатьДанные(Запрос)
	СтруктураРезультата = ОбменДанными.ПолучитьОбработатьДанные(Запрос);
	Ответ = Новый HTTPСервисОтвет(СтруктураРезультата.КодСостояния);
	Ответ.УстановитьТелоИзСтроки(СтруктураРезультата.РезультатВыполнения);	
	Возврат Ответ;	
КонецФункции

Подключаем к своему проекту Retrofit. 

// retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.6.2'
    implementation 'com.squareup.retrofit2:converter-gson:2.6.2'


Создаем интерфейс, где будут наши методы для запроса или отправки данных
 

public interface ApiService {
    @GET("{secondURL}/{id}/products")
    Call<List<RetrofitProduct>> getListProducts(@Path(value =  "secondURL", encoded = true) String secondURL, @Path("id") String id_client);
}

RetrofitProduct - это класс, список объектов которого будут созданы библиотекой автоматически, при успешном получении данных с сервера.

public class RetrofitProduct {
    @SerializedName("ID")
    @Expose
    private String iD;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("name")

// далее геттеры и сеттеры
}

Кстати, его можно автоматически сгенерировать на этом вот сайте https://www.jsonschema2pojo.org/
если у вас есть данные в формате  json.


Создаем класс синглтон для настройки клиента и авторизации на стороне 1С  

public class RetrofitClient {
    private static Retrofit retrofit = null;
    // временно, логин и пароль для подключения будем хранить в настройках?
    private static String user = "admin";
    private static String pwd = "admin";

    public static Retrofit getClient(String baseUrl) {
        if (retrofit == null) {
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .readTimeout(300, TimeUnit.SECONDS)
                    .addInterceptor(new BasicAuthInterceptor(user, pwd))
                     .build();


            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();



        }
        return retrofit;
    }

}

Для авторизации на стороне 1С используем класс BasicAuthInterceptor

class BasicAuthInterceptor implements Interceptor{
    private String credentials;

    public BasicAuthInterceptor(String user, String password) {
        credentials = Credentials.basic(user, password);
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request authenticatedRequest = request.newBuilder()
                .addHeader("Authorization", credentials)
                .build();
        return chain.proceed(authenticatedRequest);
    }

}


определим класс для инициализации библиотеки
 

public class ApiUtils {
    private static String BASE_URL;
    private ApiUtils(){}

    public static ApiService getAPIService() {
        BASE_URL = App.getBaseURL();
        try {
            return RetrofitClient.getClient(BASE_URL).create(ApiService.class);
        }catch (Exception e) {
            MyLog.e(e.toString());
            return null;
        }


    }

}

Инициализация клиента в коде

mApiService = ApiUtils.getAPIService();
  if (mApiService == null) {
          return;
  }

И собственно дергаем нужный нам метод

   try {
            response = mApiService.getListProducts(
                    App.getDefaultSecondURL(), App.CONSTANT_ID_PARTNER)
                        .execute();
            if (response.isSuccessful()) {
                somethingToDo(response.body()); // тут у нас List<RetrofitProduct>

            }else {
                String errorMessage = response.raw().toString() + "\n" //response.raw() - сырые данные, можно получить ответ сервера
                        + response.errorBody().string();

           }
        }catch (IOException e) {
            // обработка исключения;
        }

Есть два варианта вызова, синхронный и асинхронный. Синхронный вызов execute() не допускается в UI-потоке. В моем случае я использую WorkManager, который выполняет задачи в своем потоке. 

Асинхронный вызов выглядит вот так
 

       mApiServiceRetrofit.getProduct(App.getDefaultSecondURL(), App.CONSTANT_ID_PARTNER).enqueue(new Callback<RetrofitProduct>() {
            @Override
            public void onResponse(Call<PostCoordinates> call, Response<PostCoordinates> response) {
                if (response.isSuccessful()) {
                   
                }else {

               }

            }
            @Override
            public void onFailure(Call<PostCoordinates> call, Throwable t) {
                


            }
        });

Можно вызывать из Activity или из Service. Но, как я уже писал выше, я использую WorkManager (https://developer.android.com/reference/androidx/work/WorkManager.html)
Он позволяет запускать фоновые задачи последовательно или параллельно, передавать в них данные, получать из них результат, отслеживать статус выполнения и запускать только при соблюдении заданных условий. И еще, на получения результата работы можно на него подписаться, что очень удобно.
 

       LiveData<WorkInfo> ld = WorkManager.getInstance().getWorkInfoByIdLiveData(workID);
        ld.observe(context, new Observer<WorkInfo>() {
            @Override
            public void onChanged(WorkInfo workInfo) {
                if (workInfo.getState().isFinished()) {
                  // to do
                  }
            }
        });

В результате, программист получает отличный и простой инструмент для обмена данными с 1С. При этом можно не только получать данные с помощью HTTP-запроса GET, но также и передавать данные с помощью HTTP-запроса POST.

 

Полное описание библиотеки на сайте разработчика: https://square.github.io/retrofit/
Для ленивых написал простой проект с одним activity, который реализует работу с Retrofit, а также с WorkManager. Проект полностью рабочий, подключаете к Android Studio и можете сразу же пробовать. Без настроек на свой сервер будете получать ответ в виде Toast, об ошибке подключения :)

Надеюсь, что статья сэкономит кому то время (и деньги) :)
 

Retrofit WorkManager 1C HTTP-сервис Android

См. также

Мобильная разработка Мессенджеры и боты Платформа 1С v8.3 1С:Конвертация данных Платные (руб)

Теперь создать telegram-бота - элементарно. Достаточно просто нарисовать блок-схему телеграм-бота, и он сразу заработает. Это возможно при использовании Графического конструктора телеграм-ботов. Это единственный конструктор ботов для telegram, чье качество и функционал подтверждены фирмой 1С, есть сертификат 1С:Совместимо. Расширение в интерактивном режиме, с помощью блок-схем, позволяет с минимальными трудозатратами создать телеграм-ботов в любой конфигурации, работающей на платформе «1С:Предприятие 8.3».

13200 руб.

27.12.2021    38193    108    161    

201

Мобильная разработка Сканер штрих-кода Терминал сбора данных Управляемые формы Мобильная платформа 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)

Сбор заказов, инвентаризация, проверка ценников, просмотр полной информации об остатках и ценах со смартфона Онлайн - все это содержит в себе решение 1С "Штрихкод-информер" (штрих-код чекер). Отправка данных со смартфона выполняется либо напрямую в открытую форму документа, отсканировав QR-код, либо в общую корзину учетной системы, не подходя к компьютеру. Кассир или оператор сможет просмотреть список присланных данных и загрузить в любую форму, поддерживающую работу с ТСД. Для работы с мобильным приложением требуется опубликовать HTTP-сервис из поставляемого расширения.

3000 руб.

03.12.2018    59288    192    103    

172

Сканер штрих-кода Терминал сбора данных Мобильная разработка Монитор заказов Оптовая торговля Розничная торговля Ценообразование, анализ цен Программист Пользователь Платформа 1С v8.3 Мобильная платформа 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Простой мобильный ТСД (терминал сбора данных) сканер для 1С для смартфонов на iOS и Android, не требующий сложных настроек и установки дополнительных программ. Обмен между Вашей 1С и мобильным приложением осуществляется через облачный сервис и расширение конфигурации. Работает с конфигурациями УТ 11, ERP, КА2, Розница 2, Розница 3, УНФ 1.6, УНФ 3.0. Полнофункциональный демо-доступ для своей конфигурации можно запросить в настройках мобильного приложения - все необходимое придет на почту автоматически.

2000 руб.

22.04.2019    97216    586    189    

321

Логистика, склад и ТМЦ Сканер штрих-кода Терминал сбора данных Мобильная разработка Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

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

3450 руб.

28.04.2023    9468    15    0    

9

Мобильная разработка Платформа 1С v8.3 Конфигурации 1cv8 Финансовые услуги, инвестиции Управленческий учет Платные (руб)

Мобильное приложение и конфигурация 1С для автоматической торговли на бирже через API Тинькофф банка. Достаточно задать настройки, нажать «Пуск», и робот сам торгует ежедневно.

7000 руб.

25.05.2022    4643    1    0    

6

Мобильная разработка WEB-интеграция Программист Мобильная платформа Абонемент ($m)

Экспериментальный релиз и простенький скрипт к нему закрывает потребности в любых видах синхронизации между устройствами Simple и между Simple и бек-системами (например 1С). По сути – это очень простой python-скрипт, который можно запустить на доступной машине, сервере или VPS и он будет связывать клиентские устройства между собой и с 1С или другими бек-системами. В самой платформе появилось для этого множество доработок для поддержки стабильного постоянного соединения, докачки больших файлов и работе в фоне. Дополнение к основной статье https://infostart.ru/1c/tools/1153616/

1 стартмани

23.08.2024    1215    6    informa1555    1    

13

Мобильная разработка Мобильная платформа Абонемент ($m)

В этом релизе собрано много нового из области интерфейса, связи, хранения и важные новые способы управления. Дополнение к основной статье https://infostart.ru/1c/tools/1153616/

1 стартмани

25.06.2024    2605    29    informa1555    0    

33
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dusha0020 1116 04.11.19 13:03 Сейчас в теме
Может стоит "данные в формате Gson" заменить по тексту на json?
Gson это библиотека Андроида для работы с json, а не формат данных.
2. WKBAPKA 215 04.11.19 13:51 Сейчас в теме
(1) да, верно! спасибо, не обратил внимание
3. FEAS88 8 12.05.20 14:01 Сейчас в теме
Спасибо за статью, помогла. Спасибо за идею авторизации через Interceptor

У меня пара вопросов:
1. Авторизация через клиента это аналог ?

OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(300, TimeUnit.SECONDS)
.addInterceptor(new BasicAuthInterceptor(user, pwd))
.authenticator(...)
.build();

2. Interceptor перехватывает все запросы ?


PS
Я начал с retrofit, возникла ошибка, потом спустился ниже okhttp и UrlHttpConection
ошибка осталась и я грешил на авторизацию, думал не правильно делаю. А оказывается у меня проблема была в другом, и сразу все уже работало.
Была запрещена работа через не защищенное соединение. в Манифесте прописал и готово!

Если кто работал с сертификатами ssl, и использовании их в андроид поделитесь опытом буду благодарен.
4. WKBAPKA 215 12.05.20 15:23 Сейчас в теме
(3) насколько я помню OKHTTP3 включен в состав библиотеки. Можно почитать у них на сайте.
А что касается защищенного соединения, то в манифесте ничего прописывать не надо. Нужно только получить разрешение на работу с Internet.
5. WKBAPKA 215 12.05.20 15:24 Сейчас в теме
(3) я в нескольких проектах выполняю запросы по защищенному соединению и ничего дополнительно не настраивал.
6. FEAS88 8 12.05.20 16:12 Сейчас в теме
(5) Если Https то ничего не надо согласен.

Я имел ввиду что если соединение НЕ защищенное, то будет ошибка, Android разрешает по умолчанию только https.

Потому что на сервере у меня нет https, сертификата , я прописывал разрешение.
7. WKBAPKA 215 12.05.20 18:00 Сейчас в теме
(6) странно, я пробовал и так и так. Возможно, это потому, что сервер использует SSL, а вы пытаетесь по http обратиться. Я с этим не сталкивался.
8. WKBAPKA 215 12.05.20 18:02 Сейчас в теме
(6) не могу подсказать, не сталкивался... как то попробую ради интереса.
9. Umix 132 05.09.20 09:54 Сейчас в теме
Здравствуйте.
Как насчет открытого получения логина/пароля, т.е. ставите "слушателя" на устройство и получаете данные для доступа к серверу.
10. WKBAPKA 215 05.09.20 13:28 Сейчас в теме
(9) не совсем понятен вопрос.
для получения информации на мобильное устройство, если оно выступает как слушатель, понадобиться некий промежуточный сервер.
а для авторизации на сервере 1С можно не использовать логин и пароль, если настроить авторизацию на сервере
11. Umix 132 05.09.20 19:32 Сейчас в теме
Поясню.
Есть приложение на мобильном устройстве, которое обменивается данными с 1С через веб или http сервисы.
На это же мобильное приложение устанавливаю приложение типа снифера.
При использовании ksoap логин и пароль легко отловить через снифер.
Использование данной библиотеки решает эту задачу?
12. WKBAPKA 215 05.09.20 19:39 Сейчас в теме
(11) как я понимаю, тут не от библиотеки зависит, а от протокола, по которому передаются данные. Если вы передаете данные по защищенному протоколу, то данные передаются в шифрованном виде...
но, думаю, что если кто то захочет получить логин пароль для соединения с сервером, вряд-ли он будет мучаться с дешифровкой передаваемых данных. APK файл легко можно открыть... если логин и пароль будут храниться в ресурсах, то найти будет не сложно. Если в коде, то тоже, если покопаться, можно будет найти.
13. WKBAPKA 215 05.09.20 19:41 Сейчас в теме
(11) если уж защищаться, то тогда надо уже использовать более сложные и продвинутые методы защиты.
На стороне 1С можно настроить авторизацию по умолчанию, а вот идентификацию самого пользователя нужно будет настраивать по своему, с помощью дополнительного логина и пароля, например.
14. WKBAPKA 215 05.09.20 19:42 Сейчас в теме
(11) и ProGuard тут не поможет )
15. Umix 132 05.09.20 19:48 Сейчас в теме
Дело не в Guard - это типичный простенький обфусикатор и при желании можно все разобрать.
Логин / пароль внутри приложения шифруется. Но передается то он уже в чистом виде)) А это можно отловить. Вот мне и интересно, можно ли как-то работать с тем же удаленным сервером и при этом защитить доступ.
16. WKBAPKA 215 05.09.20 19:50 Сейчас в теме
(15) он не так уж и прост, если в нем разобраться.
А что значит, логин пароль шифруется? Ну шифруется и дальше что?
Что мне мешает, как хацкеру использовать шифрованный логин пароль для получения доступа?
18. Umix 132 05.09.20 20:03 Сейчас в теме
(16) получив шифрованный пароль парсером или иным способом его использовать не представляется возможным.
19. WKBAPKA 215 05.09.20 20:05 Сейчас в теме
(18) зачем его парсить когда его можно использовать в шифрованном виде?!
20. Umix 132 05.09.20 20:06 Сейчас в теме
(19) в шифрованном - это лишь мусор.
22. WKBAPKA 215 05.09.20 20:07 Сейчас в теме
(18) HTTP сервис не дает вам доступ к серверу, верно? он лишь дает вам возможность получить только те данные, что он умеет возвращать. Все остальное закрыто.
Вы можете использовать дополнительные механизмы авторизации при обмене, но хранить любые шифрованные пароли на стороне клиента нет смысла
24. Umix 132 05.09.20 20:11 Сейчас в теме
(22) верно, когда удаленный пользователь - как клиент внутри своего англомирата / компании. А когда я хочу ограничивать длительность лицензии, то мне нужна проверка на моем сервере, поэтому нужна уникальность устройства, а подключение хочется не показывать, но и защитить свои данные, да и пользователи уже привыкли получать приветственный бесплатный период для тестов и работы.
26. WKBAPKA 215 05.09.20 20:14 Сейчас в теме
(24) тогда стоит смотреть в сторону аутентификации с помощью токенов
https://tyapk.ru/blog/post/authentication-methods
как вариант
28. Umix 132 05.09.20 20:16 Сейчас в теме
(26) Да думал я уже об этом, но не решает задачу уникальности идентификации устройства.
29. WKBAPKA 215 05.09.20 20:18 Сейчас в теме
(28) это реально проблема. В Android 10 получить уникальный ID телефона или IMEI уже нельзя.
Сам, для одного своего проекта, пытаюсь придумать, как идентифицировать устройства не требуя регистрации пользователя.
27. WKBAPKA 215 05.09.20 20:15 Сейчас в теме
(24) но даже простой обмен данными по SSL протоколу не даст возможности дешифровать данные, если не получить физический доступ к устройству.
17. WKBAPKA 215 05.09.20 19:52 Сейчас в теме
(15) можно работать с удаленным сервером с защитой доступа. Для этого достаточно обменяться с сервером необходимыми данными. Вплоть до того, что можно использовать методы, что используют банки для авторизации пользователя.
Вопрос только в желании и в финансах.
21. Umix 132 05.09.20 20:07 Сейчас в теме
К сожалению мы пока не банки)))
И про промежуточный сервер думал и алгоритм 2-го шифрования и ... забыл как его... когда сначала передается открытый ключ потом...

... все это лечится обычным хардресетом, или удалением/установкой. Нужно макс простота для пользователя с защитой для себя
23. WKBAPKA 215 05.09.20 20:11 Сейчас в теме
(21) самое надежное, это высылать одноразовый пароль на номер телефона... все остальное легко ломается... ну или пользователь должен при каждой сессии вводить свой пароль. Если у вас будет свой SSL сертификат, не думаю, что кто-то сможет дешифровать данные.
Другое дело, если пользователь кому-то даст свой пароль... но это уже другая история.
25. WKBAPKA 215 05.09.20 20:11 Сейчас в теме
(21) а хранить данные для идентификации, хоть и в шифрованном виде, бесполезно. Кому надо, тот найдет
30. pvlunegov 158 10.09.20 11:22 Сейчас в теме
Скачал ваш готовый проект под Android. Сборка проекта удалась сразу, все отлично.
Установил эмулятор Android Genymotion, установил на нем устройство с api 21 (в вашем проекте указан минимальный api 19), запустил проект на запущенном эмуляторе Android. Инсталляция на запущенный эмулятор из Android studio прошла успешно, при запуске приложения на устройстве (после инсталляции) возникает ошибка (см. приложенные файлы)
Retrofit Example has stopped
Прикрепленные файлы:
31. WKBAPKA 215 10.09.20 11:31 Сейчас в теме
(30) сложно сказать. Я проверял у себя - проект рабочий. Посмотрите в дебагере на чем падает. Возможно проблема в эмуляторе, не могу сказать, т.к. я эмулятор Android Genymotion не использовал в своей работе. В любом случае надо смотреть логи ошибок.
32. pvlunegov 158 10.09.20 12:04 Сейчас в теме
(31) Запускал дебаггер, ставил точки останова.
Точки останова не срабатывают.
Подскажите какой эмулятор вы используете?
34. WKBAPKA 215 10.09.20 12:41 Сейчас в теме
(32) стандартный, который идет вместе с Android Studio
посмотрите логи, в логах точно есть описание ошибки
33. pvlunegov 158 10.09.20 12:27 Сейчас в теме
Обнаружил проблему как с Genymotion эмулятора достучатся до localhost. На localhost у меня опубликован rest odata интерфейс к базе 1с. В браузере этот интерфейс прекрасно открывается и выдает xml. В Genymotion эмуляторе также удалось достучатся до страниц с odata интерфейсом и получить xml страницы в браузере на эмуляторе.
Я подставлял ip и адрес страниц на localhost в класс App, приложение не запускается.
Догадался, что приложение не читает интерфейс odata.
Попробую в 1с создать и опубликовать http-сервис и установить его адрес в классе App
О Результатах отпишусь.
35. WKBAPKA 215 10.09.20 12:41 Сейчас в теме
OData Retrfit не поддерживает, только REST
36. pvlunegov 158 10.09.20 13:29 Сейчас в теме
В пустой базе создал http-сервис, прописал все согласно статье https://infostart.ru/public/302876/
В браузере по адресу http-сервиса получил пустую страницу, так как возвращаю ответ в виде статуса 200. Так и должно быть. Ошибок нет, ответ от http-сервиса получен (в виде статуса 200).
Прописал адрес http-сервиса в браузере эмулятора Android, получил пустую страницу (так и нужно, ошибок нет, в 1с точка останова у http-сервиса срабатывает). Следовательно http-сервис в браузере эмулятора срабатывает без проблем.
В Android studio, Прописал в вашем приложении ip, адрес http-сервиса, указал имя пользователя и пароль для авторизации.
Собрал приложение, запустил на эмуляторе - не работает, при запуске пишет - к сожалению приложение остановлено (unfortunately, Retrofit Example has stopped).
В Android studio ставил точки останова, они не срабатывают.
Просьба помочь.
37. pvlunegov 158 10.09.20 13:35 Сейчас в теме
(36) Уточняю - при начале дебага (запуск приложения с отладкой в Android studio), в приложении возникает ошибка, но точка останова в MainActivity в OnCreate срабатывает.
38. pvlunegov 158 10.09.20 13:42 Сейчас в теме
(36) С помощью дебага выявил наконец то ошибку:
Unable to start activity ComponentInfo{ua.com.service.kubik.it.retrofitexample/ua.com.service.kubik.it.retrofitexample.MainActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class Button
39. WKBAPKA 215 10.09.20 13:45 Сейчас в теме
(38) может все же попробуете эмулятор поменять?
Button стандартный компонент Android. Возможно вам имеет смысл переустановить
Android Studio
В последних версиях студии эмуляторы значительно быстрее работают, чем более ранние версии.
40. WKBAPKA 215 10.09.20 13:49 Сейчас в теме
Код на который ругается

<Button
android:id="*+id/idbutton"
android:layout_width="150dp"
android:layout_height="94dp"
android:background="*drawable/btn_circle"
android:text="*string/clickme"
android:textColor="*color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
41. pvlunegov 158 10.09.20 14:10 Сейчас в теме
На английских форумах обнаружил и обезвредил источник проблемы.
Вот обсуждение бага - https://github.com/chrisjenx/Calligraphy/issues/417
Решение (помогло решить баг):
в проекте по пути \RetrofitExample\app\src\main\res\drawable-v24
есть файлы btn_circle.xml и ic_launcher_foreground.xml
создал новую папку \RetrofitExample\app\src\main\res\drawable
перенес эти 2 файла в эту папку.
Проблема решена, приложение корректно запускается и работает на Эмуляторе!

Как я понял из обсуждения бага, на различных версиях устройств Android может быть различные разрешения экрана. Если у вас изображения (вашей кнопки) в папке drawable-v24 значит они будут поддерживаться только определенными разрешениями экранов устройств (соотношение сторон v24). Чтобы на других устройствах такой ошибки не было, нужно изображения кидать в папку drawable тогда эти изображения будут поддерживаться всеми устройствами с любым соотношением сторон экрана.

Знайте мат часть!
44. WKBAPKA 215 10.09.20 14:16 Сейчас в теме
(41) честно говоря, сталкиваюсь с этим впервые. Реализовал ряд коммерческих проектов, в которых использую графические ресурсы и под разрешение экрана не заморачивался. Работает на любом эмуляторе, на любом устройстве с разными разрешениями. Да и ресурсы созданы автоматически при создании проекта.
Думаю, что это проблема эмулятора.
46. WKBAPKA 215 10.09.20 14:19 Сейчас в теме
(41)
может быть из за этого

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<stroke
android:color="*color/colorPrimary"
android:width="5dp" />
<solid
android:color="*color/colorAccent"/>
<size
android:width="*dimen/fab_margin"
android:height="*dimen/fab_margin"/>
</shape>
</item>

</selector>

в Андроид много разных приколов, я уже ничему не удивляюсь )
47. WKBAPKA 215 10.09.20 14:31 Сейчас в теме
(41)
Возможно из за кода, для создания овальной кнопки
А так все ресурсы стандартные, сгенерированы автоматически. Но я не удивляюсь, в Андроид много разных приколов.
42. WKBAPKA 215 10.09.20 14:10 Сейчас в теме
попробуйте переделать разметку, вместо ConstraintLayout используйте LinearLayout, и замените ссылку на разметку в MainActivity
43. pvlunegov 158 10.09.20 14:13 Сейчас в теме
Огромное спасибо за ваш проект, мне это помогло решить мою давнюю потребность в интеграции Android приложения с 1с.
Все замечательно работает, я бесконечно вам благодарен!

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

Вскоре намерен развить ваш подход в своих проектах.
Как только получится что-нибудь интересное, опубликую.

Приглашаю вас к обмену информацией в переписке.
Успехов вам!
45. WKBAPKA 215 10.09.20 14:17 Сейчас в теме
(43) рад буду обмениваться информацией
48. supp 3 30.08.22 22:17 Сейчас в теме
BASE_URL = App.getBaseURL();

здесь App Это что?
49. WKBAPKA 215 30.08.22 22:52 Сейчас в теме
(48) App - это статический класс, расширяющий Application... но по факту это может быть любой статический класс
50. supp 3 30.08.22 23:51 Сейчас в теме
(49) Спасибо. А можно концовку подробней? Не понятно как в результате асинхронный вызов запустить и с примерами url
51. WKBAPKA 215 10.09.22 15:34 Сейчас в теме
(50)
            mApiService.getData(
                    App.getSecondUrl(Constants.SECOND_URL)).enqueue(
                    new Callback<List<RetrofitData>>() {
                        @Override
                        public void onResponse(@NonNull Call<List<RetrofitData>> call, @NonNull Response<List<RetrofitData>> response) {
                            

                        }

                        @Override
                        public void onFailure(@NonNull Call<List<RetrofitData>> call, @NonNull Throwable t) {
                           
                        }
                    }
            );

Показать


простой пример асинхронного вызова
RetrofitData - класс в который данные будут преобразованы
Оставьте свое сообщение