Почему использование Бойкие функции?

Вы должны добавить addCallAdapterFactory(LiveDataCallAdapterFactory()) в Retrofit Adapter.

Я реализовал с помощью Dagger-2: -

@Module(includes = [ViewModelModule::class])
        class AppModule {
        @Singleton
        @Provides
        fun provideGithubService(): GithubService {
            return Retrofit.Builder()
                .baseUrl("YOUR URL")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(LiveDataCallAdapterFactory())
                .build()
                .create(GithubService::class.java)
        }
      }

Создайте класс интерфейса, например GithubService: -

interface GithubService {
    @GET("users/{login}")
    fun getUser(@Path("login") login: String): LiveData>
}

Внедрите класс GithubService, и тогда вы сможете получить: - [119 ]

githubService.getUser(login)

LiveDataCallAdapterFactory будет выглядеть следующим образом

import androidx.lifecycle.LiveData
import com.android.example.github.api.ApiResponse
import retrofit2.CallAdapter
import retrofit2.CallAdapter.Factory
import retrofit2.Retrofit
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

class LiveDataCallAdapterFactory : Factory() {
    override fun get(
            returnType: Type,
            annotations: Array,
            retrofit: Retrofit
    ): CallAdapter<*, *>? {
        if (Factory.getRawType(returnType) != LiveData::class.java) {
            return null
        }
        val observableType = Factory.getParameterUpperBound(0, returnType as ParameterizedType)
        val rawObservableType = Factory.getRawType(observableType)
        if (rawObservableType != ApiResponse::class.java) {
            throw IllegalArgumentException("type must be a resource")
        }
        if (observableType !is ParameterizedType) {
            throw IllegalArgumentException("resource must be parameterized")
        }
        val bodyType = Factory.getParameterUpperBound(0, observableType)
        return LiveDataCallAdapter(bodyType)
    }
}

Для справки вы можете посмотреть эту ссылку https://github.com/googlesamples/android-architecture-components/tree/master / GithubBrowserSample

29
задан Philip Withnall 11 September 2017 в 18:12
поделиться

6 ответов

В общем, цель GLib - это библиотека утилит и переносимости. Это само по себе является причиной, чтобы рассмотреть возможность его использования.

Конкретные функции, о которых вы упомянули, предлагают что-то дополнительное в дополнение к их вариантам стандартной библиотеки C:

  • g_strdup_printf похоже на sprintf, но фактически выделяет буфер для вас и сохраняет вас догадка о том, насколько большим должен быть буфер. (Возвращаемое значение должно быть g_free 'd.)
  • g_free аналогично free, но проверяет наличие NULL-указателя.
  • g_strcmp0 похож на strcmp, но обрабатывает NULL-указатель как пустую строку и таким образом сортирует его впереди.
30
ответ дан jvperrin 28 November 2019 в 01:46
поделиться

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

Портативность


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

Давайте возьмем пример g_free, так как многие его критикуют. Существуют платформы, на которых free(NULL) выйдет из строя , даже если C99 говорит, что он должен работать. Эта проверка существует как минимум с 1998 года (я отслеживал ее в истории git). Некоторые могут сказать, что это больше не нужно, но даже в 2017 году я работал в компании, которая проверяет NULL, прежде чем звонить free, потому что в противном случае это может привести к сбою на их встроенной платформе. Он также служит оболочкой для внедрения вашего кода, когда вы хотите выполнить серьезную отладку памяти.

Читаемость


Это помогает улучшить читабельность вашего кода, предоставляя некоторые функции-обертки, которые не только улучшают переносимость, но и помогают избежать многих языковых ошибок. Кто из вас проверяет malloc, чтобы увидеть, вернется ли он NULL? У скольких из вас есть способ восстановиться, если он вернет NULL, поскольку у вас в основном недостаточно памяти?

g_malloc прервет приложение, если оно не сможет выделить то, что вы хотите, и в многие приложения, это просто поведение, которое вы хотите. Для очень больших распределений, которые могут потерпеть неудачу, у вас есть g_try_malloc. Это то же самое, что и malloc, но, тем не менее, дает вам преимущество в качестве обертки, которую можно использовать для измерительных приборов.

Возможность написать:

char *buffer = g_malloc(30);
/* Do something with it ... */
g_free (buffer);

... освобождает разум и позволяет разработчику сосредоточиться на задаче, которую она пытается достичь. Это также позволяет избежать сбоя вашей программы намного позже, потому что она пытается писать, используя указатель NULL, и вы должны отслеживать распределение.

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

Особенности


Другой момент - это целая куча типов коллекций, которые предоставляет GLib, и что вам не нужно переопределять. То, что переопределение связанного списка легко, не означает, что вы должны это делать. Я работал в другой компании, которая поставляла код с несколькими реализациями связанных списков, потому что некоторые разработчики просто имели бы синдром Not Invented Here и перерабатывали свои собственные. Обычная, тщательно проверенная, широко распространенная библиотека, такая как GLib, помогает избежать этой чепухи. Вы не должны перестраивать этот материал, если у вас нет особых ограничений производительности.

3
ответ дан liberforce 28 November 2019 в 01:46
поделиться

10 лет назад использование библиотеки Gnome, возможно, имело смысл, но теперь это наследство. C89, пожалуй, самый стандартный язык в мире, с очень стабильными функциями и синтаксисом, поэтому отладка чужого кода C89 выполнима.

В отличие от glib Gnome изменяет функции своей функции вне стандарта C, так что вы не только сталкиваетесь с отладкой неясного кода-обертки, созданного на C, но и ваш код может перестать работать, потому что Gnome меняет свои функции-обертки.

Приложение A: g_snprintf ()

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

См. Также g_strdup_printf ().

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

Возвращаемое значение g_snprintf () соответствует функции snprintf (), стандартизированной в ISO C99. Обратите внимание, что это отличается от традиционного snprintf (), который возвращает длину выходной строки.

Строка формата может содержать позиционные параметры, как указано в спецификации Unix.

Я менее взволнован тем, что могу написать (еще один) связанный список, чтобы заменить Gnome, И еще одну версию snprintf () и кучу дерьмового кода-обертки, который молча использует malloc (), тем самым нарушая один абсолютный максимум кодирования C: «всегда malloc () и free () в одной и той же области видимости» , чтобы заменить g_strdup_printf ().

g_strdup_printf ()

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

Добавьте к этому острые ощущения от внесения огромного количества строковых изменений в коде для выполнения «полезных» вещей, таких как изменение gchar на char, gint на int, gboolean на bool и т. Д. И т. Д. И т. Д., И т. Д., до тошноты, пока мои сравнения Subversion не стали телефонной книгой. Хуже того, в конечном итоге вам придется менять все больше и больше кода, потому что этот материал забросан по всем файлам .h, поэтому он продолжает разрастаться, как упавший на воду труп, в огромный беспорядок.

Если вы ищете работу по контракту и где-нибудь видите glib.h , ВЫПОЛНИТЕ !!! Просто скажите НЕТ!

PS: Загрузка исходного кода, удаление всех типов, специфичных для Gnome, и перекомпиляция его для создания ваших собственных «g _» функций, вроде бы, вроде работает и значительно экономит время.

Приложение B: g_strdup_printf ()

Более ужасный гном-краппола из Гнома. В Gnome есть множество «прекрасных» функций, таких как g_strdup_vprintf (), которые «волшебным образом» знают, сколько памяти нужно для хранения возвращаемой строки, и у меня была возможность заглянуть за «магию». Это выигрывает мою награду за самое отвратительное злоупотребление С когда-либо.

Если вы продолжаете отслеживать g_strdup_vprintf () через все функции-оболочки, вы попадаете в этот камень в gmessages.c ....

/**
 * g_printf_string_upper_bound:
 * @format: the format string. See the printf() documentation
 * @args: the parameters to be inserted into the format string
 *
 * Calculates the maximum space needed to store the output
 * of the sprintf() function.
 *
 * Returns: the maximum space needed to store the formatted string
 */
gsize
g_printf_string_upper_bound (const gchar *format,
                             va_list      args)
{
  gchar c;
  return _g_vsnprintf (&c, 1, format, args) + 1;
}

ЛЮБАЯ функция printf () не только медленнее, чем snot при абсолютном нуле, вы заметите, что они выделяют для хранения целый байт, да, целый gchar c, что гарантирует переполнение, но тогда кого это волнует? они получают длину строки, которая им понадобится для malloc () - потому что они собираются развернуться и снова выполнить весь printf () - на этот раз «волшебным образом» с достаточным объемом памяти.

Конечно, они добавят +1 к размеру, так что у вас будет место для nul-терминатора, гарантировано, конечно, за ужасную цену, но они так глубоко скрыли это в коде они держат пари, что вы просто сдадитесь и будете использовать его вслепую и не заметите, что это за огромный пердеж. Ну и дела, спасибо, ребята. Я просто люблю свой код для сканирования.

Не позволяйте функции _g_vsnprintf () сбить вас с толку, потому что в gprintfint.h вы обнаружите, что маленький драгоценный камень - это просто другое имя для простого старого ванили vsnprintf ();

/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GLib Team and others 2002.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
 */

#ifndef __G_PRINTFINT_H__
#define __G_PRINTFINT_H__

#ifdef HAVE_GOOD_PRINTF

#define _g_printf    printf
#define _g_fprintf   fprintf
#define _g_sprintf   sprintf
#define _g_snprintf  snprintf

#define _g_vprintf   vprintf
#define _g_vfprintf  vfprintf
#define _g_vsprintf  vsprintf
#define _g_vsnprintf vsnprintf

#else

#include "gnulib/printf.h"

#define _g_printf    _g_gnulib_printf
#define _g_fprintf   _g_gnulib_fprintf
#define _g_sprintf   _g_gnulib_sprintf
#define _g_snprintf  _g_gnulib_snprintf

#define _g_vprintf   _g_gnulib_vprintf
#define _g_vfprintf  _g_gnulib_vfprintf
#define _g_vsprintf  _g_gnulib_vsprintf
#define _g_vsnprintf _g_gnulib_vsnprintf

#endif

#endif /* __G_PRINTF_H__ */

Настоятельно рекомендуется снова посмотреть «Волшебника страны Оз», прежде чем работать с Gnome, так что вы не будете заглядывать за кулисы. Добро пожаловать в мой кошмар!

Любой, кто думает, что Gnome более устойчив, чем C, испытывает недостаток в критическом мышлении. Вы торгуете производительностью и прозрачностью ради нескольких хороших вещей, которые лучше выполняются в STL. [1 125]

-1
ответ дан Cœur 28 November 2019 в 01:46
поделиться

Для единообразного поведения в нескольких операционных системах. Это портативность.

В некоторых других средах UNIX, отличных от Linux, или если ваша программа скомпилирована в Windows, некоторые из этих функций могут не существовать или вести себя по-другому в целевой операционной системе.

Использование версий glib обеспечивает согласованное поведение.

7
ответ дан 28 November 2019 в 01:46
поделиться

Их поведение четко определено на любой платформе, поддерживаемой GTK +, в отличие от собственных функций, которые, возможно, иногда могут частично работать.

4
ответ дан 28 November 2019 в 01:46
поделиться

Я должен сказать, что это сделано хорошо, но плохо выполнено. Приятно, что ваша программа не выйдет из строя и не сгорит, если вы попытаетесь освободить () указатель более одного раза. Или отсортируйте NULL-строку. Но это смешанное благословение. Это также предотвращает обнаружение этих неприятных ошибок в вашем коде. Мало того, что вам когда-нибудь будет сложно портировать вашу программу, потому что вы полагаетесь на нестандартные функции, вам будет действительно трудностей, потому что ваш код был ошибочным, и вы так и не узнали .

3
ответ дан 28 November 2019 в 01:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: