Skip to content

Latest commit

 

History

History
377 lines (272 loc) · 9.61 KB

README.md

File metadata and controls

377 lines (272 loc) · 9.61 KB

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!")
    }
}