Skip to content

whoisjeeva/hiper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hiper

Release Build Status License GitHub repo size GitHub open issues

Hiper - A Human Friendly HTTP Library for Android

Hiper is for human by human.

Table of Contents

Getting Started

Add it in your root build.gradle at the end of repositories

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Add the dependency

implementation "com.github.whoisjeeva.hiper:http:$hiper_version"

For utils

implementation "com.github.whoisjeeva.hiper:util:$hiper_version"

Using The HTTP Library

Create a hiper instance. You can use the Hiper in two different ways.

  1. Synchronous: This will wait for the response, this will block whatever thread it is running on.
  2. Asynchronous: This won't wait or block the running thread, instead you pass callbacks and it will execute those callbacks when it succeed or fail.
val hiper = Hiper.getInstance() // for synchronous requests
// or
val hiper = Hiper.getInstance().async() // for asynchronous requests

Now you are ready to see the power of hiper.

Sending a simple GET request

val caller = hiper.get("http://httpbin.org/get") { response ->
    debug(response.text)
}

Sending a simple POST request

val caller = hiper.post("http://httpbin.org/post") { response ->
    debug(response.this)
}

Sending GET parameters with your request

val caller = hiper.get("http://httpbin.org/get", args = mix("name" to "Hiper", "age" to 1)) {
    debug(this)
}

Or you can use inline args, headers, cookies or form using the mix method

hiper.get("http://httpbin.org/get", args = mix("name" to "Hiper"), headers = mix("user-agent" to "Hiper/1.0")

Using custom headers

val caller = hiper.get("http://httpbin.org/get", headers = mix("User-Agent" to "Hiper/1.1")) {
    debug(this)
}

Downloading a file using Hiper.

val caller = hiper.get("http://httpbin.org/get", isStream = true) {
    // do things with the stream
    ...
    stream.close()
}

Using The Utils Library

The utils library contains few useful method that will makes your android development little bit easier.

Context.toast(o: Any?, isLong: Boolean = false)

Showing a toast message is easier with this extension method.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        toast("hello, world")
    }
}

debug(vararg args: Any?), error(vararg args: Any?), warn(vararg args: Any?), info(vararg args: Any?)

When we debug our application we use the Log.d a lot, it requires a TAG and a String as value. With the debug method we can pass any value and it will use the class name wherever it called from as TAG (with .kt extension).

val person = Person()
debug(person)

onUiThread(callback: () -> Unit)

Switch to UI thread even without an Activity. It uses coroutines to run your code in the UI thread.

class MyService: Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        thread {
            ...

            onUiThread {
                toast("Done.")
            }
        }
    }
}

async(block: suspend CoroutineScope.() -> Unit)

Launch a coroutine using the Dispatchers.IO

async {
    // do your background tasks
}

sleep(millis: Long)

Suspend async for specified milliseconds. Only valid inside a coroutine scope.

async {
    ...
    sleep(1000) // 1 second
}

CoroutineScope.run(block: () -> Unit)

Run blocking code inside async

async {
    ...
    run {
        // blocking code
    }
}

Context.isDarkThemeOn(): Boolean

Check if the system dark mode is enabled

if (isDarkThemeOn()) {
    // switch sh to dark mode
}

Context.readFile(dir: String, fileName: String): ByteArray

Read a file from getExternalFilesDir

val data: ByteArray = readFile(Environment.DIRECTORY_DOWNLOADS, "test.txt")

Context.readFromRawFolder(path: String): ByteArray

Read a file from raw folder

// R.raw.test
val data: ByteArray = readFromRawFolder("test")

fetch(url: String, callback: BufferedReader.() -> Unit)

Send a simple GET http request

fetch("https://httpbin.org/ip") { reader ->

}

WeeDB(appContext: Context)

Creating a WeeDB instance.

val wee = WeeDB(applicationContext)

Storing and retrieving primitive data type.

wee.put("age", 26)
debug(wee.getInt("age"))

wee.put("name", "Jeeva")
debug(wee.getString("name"))

Storing a List that contains Any datatype. In this case wee.getList returns WeeList. Which is a dynamic list that can store any type data. but when you directly access the data you will get back the String version of the data. Because WeeDB stores everything as a String. In order to get a data with a specific datatype, you need to call an appropriate get method.

wee.put("names", listOf("Jeeva", "Fearless", 5, true))
val names = wee.getList("names")
debug(names[2]) // "5"
debug(names.getInt(2)) // 5

Storing a specific type List.

val scores = wee.newList("scores", Int::class.java)
scores.add(40)
scores.add(72)
scores.add(35)
scores.add(98)
debug(scores[0]+1) // 41

Storing a Parcelable data. Add the kotlin-parcelize plugin.

// app build.gradle
plugins {
    ..
    id 'kotlin-parcelize'
}
@Parcelize
data class Person(val name: String, val age: String): Parcelable

wee.put("jeeva", Person("Jeeva", 26))
debug(wee.get("jeeva", Person::class.java).name)

Working with Parcelable list.

val jeeva = Person(name = "Jeeva", age = 26)
val senkathir = Person(name = "Senkathir", age = 15)

val persons = wee.newList("persons", Person::class.java)
persons.add(jeeva)
persons.add(senkathir)

debug(persons[0].name) // Jeeva

Looping through WeeDB list.

val persons = wee.newList("persons", Person::class.java)
persons.add(jeeva, senkathir)

for (person in persons) {
    debug(person.name)
}

Check if a key exists in WeeDB.

wee.put("person", Person(name = "Jeeva", age = 26))
if ("person" in wee) {
    // ...
}

Check if a value exists in WeeDB list.

NOTE: Only works in a WeeDB list

val persons = wee.newList("persons", Person::class.java)
persons.add(jeeva, senkathir)

if (Person(name = "Jeeva", age = 26) in persons) {
    // ...
}

StateDB(name: String)

Initialize inside a composable function

@Composable
fun App() { 
    val stateDB = rememberStateDB(name = "test_store")
    val age by stateDB.getString("age").collectAsState(initial = 27)

    Button(onClick = {
        async {
            stateDB.put("age", age+1)
        }
    }) {
        Text(text = "Click me!")
    }
}