Skip to content

Instantly share code, notes, and snippets.

View hoangchungk53qx1's full-sized avatar
😆
Out sick

hoangchung hoangchungk53qx1

😆
Out sick
View GitHub Profile
import android.media.MediaDrm
import android.media.UnsupportedSchemeException
import android.os.Build
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.UUID
object DeviceUtils {
fun getUniqueDeviceId(): String? {
@hoangchungk53qx1
hoangchungk53qx1 / proguard-rules.pro
Created August 20, 2024 03:33
Popular proguard rule
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:

suspend function trung tâm trong coroutine Đối với 1 lập trình viên Mobile nói chung, và Android nói riêng, trước đây đối với mình, RxJava, RxKotlin, RxAndroid nói chung Rx style và reactive là thứ gì đó tuyệt vời để asynchonous task

Từ khi coroutines ra đời, các lập trình viên Android chuyển sang dùng nhiều hơn vì nó dễ dùng hơn Rx, vì Rx dùng sâu khá khó nuốt.

Đối với coroutine thì các bạn khá dễ dùng rồi, cũng như lợi ích của nó rồi, trong bài viết này mình sẽ không nói tới cách dùng và lợi ích của nó nữa mà phân tích kỹ hơn về vấn đề suspend function

Có thể nói suspend function là trung tâm trong vũ trụ Coroutine.

Không giống như function thường, suspend function không block bất kì thread nào mà nó chạy trên đó, nói thuần tiếng việt nó là function có khả năng tạm dừng và tiếp tục,và huỷ và nó hoàn toàn non-blocking...

@Query("UPDATE leaderboard_db SET " +
"dbplayerPoints1 = CASE WHEN dbplayerName1 = :playerName THEN :newPoints ELSE dbplayerPoints1 END, " +
"dbplayerPoints2 = CASE WHEN dbplayerName2 = :playerName THEN :newPoints ELSE dbplayerPoints2 END, " +
"dbplayerPoints3 = CASE WHEN dbplayerName3 = :playerName THEN :newPoints ELSE dbplayerPoints3 END, " +
"dbplayerPoints4 = CASE WHEN dbplayerName4 = :playerName THEN :newPoints ELSE dbplayerPoints4 END, " +
"dbplayerPoints5 = CASE WHEN dbplayerName5 = :playerName THEN :newPoints ELSE dbplayerPoints5 END, " +
"dbplayerPoints6 = CASE WHEN dbplayerName6 = :playerName THEN :newPoints ELSE dbplayerPoints6 END, " +
"dbplayerPoints7 = CASE WHEN dbplayerName7 = :playerName THEN :newPoints ELSE dbplayerPoints7 END, " +
"dbplayerPoints8 = CASE WHEN dbplayerName8 = :playerName THEN :newPoints ELSE dbplayerPoints8 END, " +
"dbplayerPoints9 = CASE WHEN dbplayerName9 = :playe
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.RoundRect
@hoangchungk53qx1
hoangchungk53qx1 / NestedScrollableHost.kt
Created February 22, 2024 09:59
NestedScrollableHost.kt
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.widget.FrameLayout
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
@hoangchungk53qx1
hoangchungk53qx1 / post.js
Created January 6, 2024 16:03
preRequestScript
const postRequest = {
url: "https://ca6e-2405-4803-fc0e-22e0-54a1-487d-d4c6-ab89.ngrok-free.app/api/auth/login",
method: 'POST',
header: {
'Content-Type': 'application/json',
},
body: {
mode: 'raw',
raw: JSON.stringify({"username" : "user1234", "password" : "User12345"})
}
@hoangchungk53qx1
hoangchungk53qx1 / FirstItemUpdatedObserver.kt
Created November 29, 2023 04:32
This observer detects when item was added or moved to the first position of the adapter
/**
* This observer detects when item was added or moved to the first position of the adapter, while recyclerView is scrolled to the top. This is necessary
* to force recycler to scroll to the top to make such item visible, because by default it will keep items on screen, while adding new item to the top,
* outside of the viewport
* @param layoutManager - [LinearLayoutManager] of the recycler view, which displays items
* @property onItemUpdated - callback to be called, when observer detects event
*/
class FirstItemUpdatedObserver(
layoutManager: LinearLayoutManager,
private val onItemUpdated: () -> Unit
@hoangchungk53qx1
hoangchungk53qx1 / requester.kt
Created November 28, 2023 10:37
FocusRequesterRestore
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import UIKit
import RxCocoa
import RxSwift
private var prepareForReuseBag: Int8 = 0
@objc public protocol Reusable : class {
func prepareForReuse()
}