🪁 Android Resources Wrapper Library

Overview

Kite

Android Resource Wrapper Library.

Download from MavenCentral Android Arsenal CircleCI Android CI Codacy Kotlin Android Min Sdk Android Compile Version License

TLDR

Fed up with typing ContextCompat, resources and context all over your apps to access your resources? Say no more.

Gradle
dependencies {
    implementation 'com.github.cioccarellia:kite:1.2.1'
}
Kotlin DSL
dependencies {
    implementation("com.github.cioccarellia:kite:1.2.1")
}
Maven
<dependency>
    <groupId>com.github.cioccarelliagroupId>
    <artifactId>kiteartifactId>
    <version>1.2.1version>
    <type>pomtype>
dependency>
  • 🪁 Access all app resources with one unified syntax.
  • 🧬 Null safe layer between the Android framework java code and your app.
  • 🧊 Transparent and lightweight wrapper.
  • 🔒 Extensive built-in checks.
  • Easy to implement in existing apps.
  • ❤️ Kotlin powered, 100%.
val text = Kite.string[R.string.welcome_back]

Usage

Kite is a handy and lightweight android library which aims at reducing redundancy and decreasing android code complexity. It encloses and simplifies resource access within the Kite domain, and abstracts away the implementation logic needed to fetch the desired value, making interactions with the android framework smooth and frictionless. To get started initialize kite (ideally inside your Application class) and pass to it the application context.

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Kite.fly(this)
    }
}

You're all set. You can now import the Kite object, select whichever resource category you want to access and fetch it using the resource id and the bracket notation [].

Beware: kite can not and will not save you from the mess that is dealing with Android Context. After all, kite is some cleverly placed syntactic sugar over those same android methods you are used to: kite itself holds a reference to Context. It will, however, unify and thoroughly uniform your experience with dealing with all android related resource extraction operations, which can turn to be extremely practical. It may also save you from typing again ContextCompat in your life. That's the precise reason kite was created.

Samples

// 🪁 Kite
fab.rippleColor =         Kite.color[R.color.md_light_lime]
fab.backgroundTintList =  Kite.colorStateList[R.color.md_lime]
fab.text =                Kite.string[R.string.unread_notifications, "69"]
fab.isVisible =           Kite.bools[R.bool.show_fab]

// Standard
fab.rippleColor =         ContextCompat.getColor(context, R.color.md_light_lime)
fab.backgroundTintList =  ColorStateList.valueOf(R.color.md_lime)
fab.text =                appContext.getString(R.string.unread_notifications, "69")
fab.isVisible =           resources.getBoolean(R.bool.show_fab)

Context Switching

One clear disadvantage to using kite with respect to doing things the old way is choosing which context to use. That's why Kite comes packed with extension functions for permanent change / temporary switch the in-use context, so that you have full control over which context is used to do what.

  • runWith can be invoked on any KiteFetcher object, it is chainable and it temporarily runs the passed lambda in the desired context.
Kite.color.runWith(this) { color ->
    button.setBackground(
        color[R.color.colorAccent]
    )
}

Supported Resources

Kite delegates resource collection to KiteFetchers. Those classes contain a well defined implementation of the actual process of converting the given id to the output type.

Resource Type AAPT class Fetcher Input Output Implementation API Variants
Strings R.string Kite.string @StringRes string: Int String Context.getString() / formatArgs
Plurals R.plurals Kite.plural @PluralRes plural: Int, quantity: Int String Resources.getQuantityString() / formatArgs
Texts R.string Kite.text @StringRes text: Int CharSequence Context.getText() / /
Color R.color Kite.color @ColorRes color: Int @ColorInt Color ContextCompat.getColor() / /
ColorStateLists R.color Kite.colorStateList @ColorRes colorStateList: Int ColorStateList ContextCompat.getColorStateList() / /
Drawables R.drawable Kite.drawable @DrawableRes drawable: Int Drawable ContextCompat.getDrawable() / Resources.Theme?
Layouts R.layout Kite.layout @LayoutRes layout: Int XmlResourceParser Resources.getLayout() / /
Integer R.integer Kite.integer @IntegerRes integer: Int Int Resources.getInteger() / /
Booleans R.bool Kite.booleans @BoolRes boolean: Int Boolean Resources.getBoolean() / /
Dimensions R.dimen Kite.dimension @DimenRes dimensions: Int Float Resources.getDimensions() / /
Fractions R.fraction Kite.fraction @FractionRes fraction: Int, base: Int, pbase: Int Float Resources.getFraction() / /
Fonts R.font Kite.font @FontRes font: Int Typeface Resources.getFont() 26 /
Animations R.anim Kite.animation @AnimRes animation: Int Animation AnimationUtils.loadAnimation() / /
Interpolators R.interpolator Kite.interpolation @InterpolatorRes interpolator: Int Interpolator AnimationUtils.loadInterpolator() / /
IntArray R.array Kite.intArray @ArrayRes intArray: Int IntArray Resources.getIntArray() / /
StringArray R.array Kite.stringArray @ArrayRes stringArray: Int Array Resources.getStringArray() / /
TypedArray R.array Kite.typedArray @ArrayRes typedArray: Int TypedArray Resources.obtainTypedArray() / /
Identifiers R.id Kite.identifier name: String, defType: String, defPackage: String Int Resources.getIdentifier() / /
Xmls R.xml Kite.xml @XmlRes xml: Int XmlResourceParser Resources.getXml() / /
Raws R.raw Kite.raw @RawRes raw: Int InputStream Resources.openRawResource() / TypedValue

⚠️ Known Issues

  • Annotation checks over resource function parameters (functions which take as argument some annotated value, like @ColorRes, @StringRes) are not extensively performed by Android Studio, when using kotlin operator functions. I created a bug report @ google issue tracker here. Hope to see it fixed soon, by 2020 2021

Kite Puns

  • A kite usually comes with different colors
  • A kite is flown and controlled with strings
Comments
  • Format arguments type missmatch

    Format arguments type missmatch

    I'm trying out your library and i found problem with using arguments in string accessor. You have operator for

    operator fun get(
            @StringRes @IntRange(from = 1) string: Int,
            vararg formatArguments: String
        ): String = kiteContext.getString(string, formatArguments)
    

    While the context getString method requires vararg arguments: Any (or Object... arguments in java).

    Nontheless - when i'm trying to pass string parameter i have this strange result: [Ljava.lang.String;@d43d4f6 hours which is caused by difference between kotlin/java vararg. You need to add * before formatAguments like this:

    operator fun get(
            @StringRes @IntRange(from = 1) string: Int,
            vararg formatArguments: Any
        ): String = kiteContext.getString(string, *formatArguments)
    

    I'd love to contribute, but i failed to build project from main branch with message

    FAILURE: Build failed with an exception.
    
    * What went wrong:
    A problem occurred configuring project ':kite'.
    > Have you created the publish closure? Missing userOrg. 
    
    * Try:
    Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Exception is:
    org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':kite'.
    	at org.gradle.configuration.project.LifecycleProjectEvaluator.wrapException(LifecycleProjectEvaluator.java:80)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:73)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator.access$600(LifecycleProjectEvaluator.java:53)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:199)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:112)
    	at org.gradle.internal.Factories$1.create(Factories.java:26)
    	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
    	at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
    	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:227)
    	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:221)
    	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:187)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:96)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:68)
    	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:693)
    	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:141)
    	at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:36)
    	at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:64)
    	at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:55)
    	at org.gradle.configuration.BuildOperatingFiringProjectsPreparer$ConfigureBuild.run(BuildOperatingFiringProjectsPreparer.java:52)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    	at org.gradle.configuration.BuildOperatingFiringProjectsPreparer.prepareProjects(BuildOperatingFiringProjectsPreparer.java:40)
    	at org.gradle.initialization.DefaultGradleLauncher.prepareProjects(DefaultGradleLauncher.java:198)
    	at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:138)
    	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:126)
    	at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:106)
    	at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:60)
    	at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:57)
    	at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:85)
    	at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:78)
    	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
    	at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
    	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:78)
    	at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:57)
    	at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:60)
    	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
    	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:51)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:45)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
    	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:78)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
    	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
    	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
    	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
    	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
    	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:59)
    	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:36)
    	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
    	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
    	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
    	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
    	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
    	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
    	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
    	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
    	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
    	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
    	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
    	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
    	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:68)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:27)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
    	at org.gradle.util.Swapper.swap(Swapper.java:38)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
    	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    Caused by: java.lang.IllegalStateException: Have you created the publish closure? Missing userOrg. 
    	at com.novoda.gradle.release.PublishExtension.validate(PublishExtension.groovy:73)
    	at com.novoda.gradle.release.ReleasePlugin$_apply_closure1.doCall(ReleasePlugin.groovy:18)
    	at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingClosure$1$1.run(DefaultListenerBuildOperationDecorator.java:185)
    	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:60)
    	at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingClosure$1.run(DefaultListenerBuildOperationDecorator.java:180)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
    	at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingClosure.doCall(DefaultListenerBuildOperationDecorator.java:177)
    	at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:41)
    	at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
    	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:231)
    	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:150)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
    	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:325)
    	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:235)
    	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:141)
    	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
    	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    	at com.sun.proxy.$Proxy38.afterEvaluate(Unknown Source)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:191)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:188)
    	at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1420)
    	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:197)
    	... 115 more
    
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 29s
    

    Also - i think this library could really use some tests to catch such issues faster :)

    bug discussion 
    opened by jakoss 6
  • Jcenter is closed

    Jcenter is closed

    Hi,

    Jcenter is closed.

    Can you publish it in other place?

    implementation "com.cioccarellia:kite:1.2.0"
    
    Could not find com.cioccarellia:kite:1.2.0.
    

    Thanks.

    opened by paulocoutinhox 5
  • Multi-window dynamic context support

    Multi-window dynamic context support

    As specified in the docs:

    After {@link Build.VERSION_CODES#R}, {@link Resources} must be obtained by {@link android.app.Activity} or
    {@link android.content.Context} created with {@link android.content.Context#createWindowContext(int, Bundle)}. 
    {@link Application#getResources()} may report wrong values in multi-window or on secondary displays.
    

    Currently kite does not support sharing and dynamically switching context. Therefore it lacks support for multi-window apps. There should be a manual mode where the context can be explicitly set every time a resource is accessed, and therefore the internal Kite context is not used in those occasions.

    enhancement android 
    opened by cioccarellia 4
  • Why Context is private?

    Why Context is private?

    Why keep context variable private? It would be helpful if we can also access the current context from Kite just like resources.

    Like :

    Kite.context and Kite.applicationContext

    discussion api 
    opened by NareshMyTeam11 3
  • Android Resource extensions

    Android Resource extensions

    Glad I'm not the only one being tired of passing through context all day. Please have a look at https://github.com/kibotu/AndroidResourceExtensions it solves the issue of having to update context yourself and also will resolve using only application context to interact with resources which will give you unthemed values and of course won't accidently leak context as well.

    Have a nice day 😊👌

    ¯\_(ツ)_/¯ 
    opened by kibotu 1
  • Enable explicit API mode, add explicit visibility and typing to comply

    Enable explicit API mode, add explicit visibility and typing to comply

    This PR enables explicit API mode, which requires explicit visibility modifiers for all declarations, and explicit types for public declarations. I made educated guesses about what you'd want public and not public in the library, most importantly, made all KiteResParser implementations internal, only exposing them through the interface.

    Also enables progressive mode as a bonus, as that's also a compiler property that can be specified the same way.

    opened by zsmb13 0
  • New methods to add

    New methods to add

    Hi,

    Im using it in our app and i want know if you can add some methods please for:

    • context.resources.getDimensionPixelOffset
    • context.resources.getDimensionPixelSize
    • context.resources.getValue
    • context.resources
    • context.resources.displayMetrics
    • context.resources.getFloat

    Thanks.

    opened by paulocoutinhox 2
Owner
Andrea Cioccarelli
20. @Kotlin Developer. @vuejs Enthusiast. Random Writer @Medium. Karate & Krav Fighter. Traveler. Polimi. 🇮🇹
Andrea Cioccarelli
Very easy to use wrapper library for Android SharePreferences

Treasure English document Treasure是一个Android平台上基于SharePreferences的偏好存储库,只需要定义接口,无需编写实现,默认支持Serializable和Parcelable。运行时0反射,不仅使用方便而且性能和原生写法几乎无差别。 使用方法 1

星一 507 Nov 12, 2022
Android Shared preference wrapper than encrypts the values of Shared Preferences. It's not bullet proof security but rather a quick win for incrementally making your android app more secure.

Secure-preferences - Deprecated Please use EncryptedSharedPreferences from androidx.security in preferenced to secure-preference. (There are no active

Scott Alexander-Bown 1.5k Dec 24, 2022
Wrapper around the android Camera class that simplifies its usage

EasyCamera Wrapper around the android Camera class that simplifies its usage (read more about the process) Usage: // the surface where the preview wil

Bozhidar Bozhanov 641 Dec 29, 2022
React Native wrapper to bridge our iOS and Android SDK

React Native wrapper to bridge our iOS and Android SDK

Intercom 94 Jan 1, 2023
Expirable Disk Lru Cache is a secure(with encryption) wrapper for [DiskLruCache](https://github.com/JakeWharton/DiskLruCache) that allows expiring of key/value pairs by specifying evictionTimeSpan. It has very simple API.

ExpirableDiskLruCache ExpirableDiskLruCache is a wrapper for DiskLruCache that allows expiring of key/value pairs by specifying evictionTimeSpan. It h

Vijay Rawat 24 Oct 3, 2022
Android library which makes it easy to handle the different obstacles while calling an API (Web Service) in Android App.

API Calling Flow API Calling Flow is a Android library which can help you to simplify handling different conditions while calling an API (Web Service)

Rohit Surwase 19 Nov 9, 2021
Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Shahid Iqbal 4 Nov 29, 2022
A robust native library loader for Android.

ReLinker A robust native library loader for Android. More information can be found in our blog post Min SDK: 9 JavaDoc Overview The Android PackageMan

Keepsafe 2.9k Dec 27, 2022
Joda-Time library with Android specialization

joda-time-android This library is a version of Joda-Time built with Android in mind. Why Joda-Time? Android has built-in date and time handling - why

Daniel Lew 2.6k Dec 9, 2022
UPnP/DLNA library for Java and Android

Cling EOL: This project is no longer actively maintained, code may be outdated. If you are interested in maintaining and developing this project, comm

4th Line 1.6k Jan 4, 2023
:iphone: [Android Library] Get device information in a super easy way.

EasyDeviceInfo Android library to get device information in a super easy way. The library is built for simplicity and approachability. It not only eli

Nishant Srivastava 1.7k Dec 22, 2022
Android library for viewing, editing and sharing in app databases.

DbInspector DbInspector provides a simple way to view the contents of the in-app database for debugging purposes. There is no need to pull the databas

Infinum 924 Jan 4, 2023
Android Market In-app Billing Library

Update In-app Billing v2 API is deprecated and will be shut down in January 2015. This library was developed for v2 a long time ago. If your app is st

Robot Media 533 Nov 25, 2022
An Android library allowing images to exhibit a parallax effect that reacts to the device's tilt

Motion An Android library allowing images to exhibit a parallax effect. By replacing static pictures and backgrounds with a fluid images that reacts t

Nathan VanBenschoten 781 Nov 11, 2022
Android library to easily serialize and cache your objects to disk using key/value pairs.

Deprecated This project is no longer maintained. No new issues or pull requests will be accepted. You can still use the source or fork the project to

Anup Cowkur 667 Dec 22, 2022
Form Validator Library for Android

Android-Validator Form Validator Library for Android [](https://flattr.com/submit/auto?user_id=throrin19&url=https://github.com/throrin19/Android-Vali

Benjamin Besse 449 Dec 17, 2022
Error handling library for Android and Java

ErrorHandler Error handling library for Android and Java Encapsulate error handling logic into objects that adhere to configurable defaults. Then pass

null 237 Dec 29, 2022
Small Android library to help you incorporate MVP, Passive View and Presentation Model patterns in your app

DroidMVP About DroidMVP is a small Android library to help you incorporate the MVP pattern along with Passive View and Presentation Model (yes, those

Andrzej Chmielewski 225 Nov 29, 2022
A simple Android utils library to write any type of data into cache files and read them later.

CacheUtilsLibrary This is a simple Android utils library to write any type of data into cache files and then read them later, using Gson to serialize

Wesley Lin 134 Nov 25, 2022