Lunski's Clutter

This is a place to put my clutters, no matter you like it or not, welcome here.

0%

Android and Kotlin

不知道一週能完成多少呢。

O

回顧Android。

KRs

  1. Compoments (100 %)
  2. 機智問答 (80 %)
  3. Kotlin (50 %)
  4. Thread (100 %)

Compoments

1
2
3
4
Activity: 提供UI,有不同狀態,User可以在UI間切換。
Service: 預設在UI thread,但長時間的操作建議使用work thread,可實現下載文件、播放音樂、後臺更新等。
Broadcast Receiver: 在系統服務與UI最好的溝通方式,預設在UI thread,但可以在onReceive()包一個新Thread,可實現系統啟動、電池電量低等功能。
Content Provider: 管理app db,提供data給其他app,是和持久資料的場景。
  • 皆開始於 UI thread.

Activity生命週期


ref


ref

  • OnCreate: Cold start
  • OnStart: Warm start
  • OnResume: Hot start

UI components represent individual screens in the app and typically handle user interactions.

1
2
3
4
5
6
7
onCreate():Activity第一次被創建,初始化Activity的狀態和布局。
onStart():Activity被啟動時調用,執行一些初始化操作,如註冊Broadcast Receiver等。
onResume():Activity從背景到使用者可視時的進入點,從onPause()啟動或恢復一些耗時操作,如開啟動畫效果等。
onPause():Activity失去焦點時調用,通常在這個方法中暫停或停止一些耗時操作,如動畫效果等。
onRestart():Activity從onStop()重新啟動時調用。
onStop():Activity不再可見時調用,通常在這個方法中釋放一些資源,如註銷Broadcast Receiver等。
onDestroy():當Activity被銷毀時調用,通常在這個方法中釋放所有的資源。

優化

Startup library: 透過 Content provider 的機制來加速 App 的開啟速度。

Service生命週期


ref

Background components perform long-running operations.

有三種服務,兩種啟動方式

  • 前台服務(Foreground Service):不在UI thread,User可見的服務
  • 後台服務(Background Service):不在UI thread,User不可見的服務
  • 繫結服務(Bound Service):繫結已經存在的服務
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class MyService extends Service {

private Thread backgroundThread;

@Override
public void onCreate() {
super.onCreate();
// Initialize your service here
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Start the background thread
backgroundThread = new Thread(new Runnable() {
@Override
public void run() {
// Perform the main functionality of your service here
}
});
backgroundThread.start();

// Return START_STICKY to indicate that the service should be restarted if it is killed
return START_STICKY;
}

@Override
public void onDestroy() {
super.onDestroy();
// Release any resources used by your service here
backgroundThread.interrupt();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
// Implement this method if you want to allow other components to bind to your service
return null;
}
}
  • onCreate()
    Service第一次被創建時調用,如創建線程等。

  • onStartCommand()
    啟動Service時調用,執行一些耗時的操作,如網絡請求等。

  • onBind()
    繫結Service時調用,返回一個IBinder對象,用於繫結Service和客戶端進行通信。

  • onUnbind()
    解除繫結Service,可以在這個方法中釋放一些資源,如註銷Broadcast Receiver等。

  • onDestroy()
    Service被銷毀時調用,通常在這個方法中釋放所有的資源。

BroadcastReceiver

Listen for system-wide events or messages and allow the app to respond to these events.

ContentProvider

Provide a consistent data interface to other apps.

程式間互相分享資料 Views System:lists,grids,text boxes,buttons…元件

1
2
3
4
5
6
7
8
9
10
11
12
import android.content.ContentProvider;

public class LogProvider extends ContentProvider {

onCreate() : 初始化
insert(Uri, ContentValues) :將新數據插入內容提供者
update(Uri, ContentValues, Bundle) :更新內容提供者中的現有數據
delete(Uri, Bundle) 從內容提供者中刪除數據
getType(Uri) 返回content provider中數據的MIME類型(檔案格式,HTML...)
ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException :檔案處理

}

ref

Android Inter-Process Communication (IPC)

  • Services
    Perform long-running operations in the background.

  • Broadcast Receivers
    Send and receive system-wide messages or broadcast custom messages.

  • Content Providers
    A data repository allow data to be shared between applications.

  • Intents
    Send messages between components of the same or different applications.

  • Messenge
    A lightweight IPC mechanism, send messages between components.

  • AIDL (Android Interface Definition Language)
    A programming language that allows the definition of interfaces between processes.

機智問答

Finally, Final and Finalize

  • Finally
    Used for exception handling

  • Final
    Variable: constants
    Method: prevent overriding
    Class: prevent inheritance

  • Finalize
    Used for performing cleanup operations on objects before they are destroyed.

Synchronized and Unsynchronized

  • Synchronized
    Block of code that can be accessed by only one thread until the first thread releases the lock.

  • Unsynchronized
    A code didn’t use synchronized keyword.

References

  • Strong reference
    Never GC

  • Soft reference
    GC before OutOfMemoryError

  • Weak referenc
    GC when there is no Strong or Soft

JNI(Java Native Interface)

A framework that allows Java code running in a JVM to call native code and vice versa.

Layouts

1
2
3
4
5
6
LinearLayout:水平/垂直。
RelativeLayout:相對於其他元素或父容器定位。
FrameLayout:元素可護疊,只顯示上層。
ConstraintLayout:設置元素之間的約束條件,實現複雜的屏幕佈局效果。
TableLayout:表格的形式排列。
GridLayout:可以定義行和列的屬性。

ListView v.s. RecyclerView

1
2
ListView:從上到下顯示佈局。
RecyclerView:多種不同的佈局,顯示大量的數據列表,例如聊天記錄、商品列表、新聞列表等,支持高效的數據重用,只顯示當前顯示區域內的數據,當列表滾動時,之前顯示的數據會被回收重用,減少了內存占用和重複創建視圖的消耗。

Kotlin

符號

  • ?/!!
1
2
val myList: ArrayList<String>? = null // null 時印null
Log.d("Tag", "List Size: "+ myList!!.size) // !! 在非空時有 NullPointerException
  • ?:
1
val mySize= myList?.size ?: 0 // myList?.size == null 時回傳0  
  • ::

把方法當參數傳遞

1
var action: (A, B) -> ReturnType
  • ==/===
1
值/位置
  • 封裝繼承比Java更簡潔,有Coroutines
  • lateinit

非null變數,之後再給值

1
2
3
4
5
6
7
8
9
10
11
12
class MyClass {
lateinit var myString: String

fun initialize() {
myString = "Hello World"
}

fun printString() {
println(myString)
}
}

  • var可賦值,val 不可
  • 類型推論(type inferred)
1
2
3
val number = 42 // number is inferred to be an Int
val message = "Hello, world!" // message is inferred to be a String
fun add(a: Int, b: Int) = a + b // inferred return type is Int
  • Range
1
2
3
4
5
6
7
8
9
val intRange = 1..10 // creates a range from 1 to 10 (inclusive)
val charRange = 'a'..'z' // creates a range from 'a' to 'z' (inclusive)
val intRange2 = 1.rangeTo(10) // equivalent to 1..10

println(intRange.last) // prints 10
println(charRange.contains('m')) // prints true

val evenNumbers = 2..10 step 2 // creates a range from 2 to 10 (inclusive) with a step of 2
println(evenNumbers) // prints 2, 4, 6, 8, 10
  • Null Safety(避免NullPointerExceptions)
1
2
3
4
5
6
var nullableString: String? = null // nullable
val nonNullString: String = "Hello" // non-null

val length = nullableString?.length // length is null if nullableString is null
val length = nullableString?.length ?: -1 // length is -1 if nullableString is null
val length = nullableString!!.length // throws NPE if nullableString is null
  • when取代switch
1
2
3
4
5
6
7
8
9
10
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}

->後也可以加{}
1
2
3
4
5
6
7
8
9
10
11
class Student(
val name: String,
val surname: String,
val passing: Boolean,
val averageGrade: Double
)

students.filter { it.passing && it.averageGrade > 4.0 } // 1
.sortedBy { it.averageGrade } // 2
.take(10) // 3
.sortedWith(compareBy({ it.surname }, { it.name })) // 4
  • Companion Object

Class中方便定義靜態函式

1
2
3
4
5
6
7
8
9
10
11
12
13
class MyClass {
companion object {
fun myStaticMethod() {
println("This is a static method.")
}
val myStaticProperty = "This is a static property."
}
}


MyClass.myStaticMethod() // Output: "This is a static method."
println(MyClass.myStaticProperty) // Output: "This is a static property."

  • 繼承用:取代extends
1
2
3
4
5
6
7
8
9
10
11
open class Animal {
open fun makeSound() {
println("...")
}
}

class Dog : Animal() {
override fun makeSound() {
println("Woof!")
}
}
  • 介面用:取代implements
1
2
3
4
5
6
7
8
9
interface Moveable {
fun move()
}

class Car : Moveable {
override fun move() {
println("Driving...")
}
}
1
fun <原class>.<新method>()
1
2
3
4
toString()
componentN()
copy()
hashCode()
  • 高階函數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
map()
val numbers = listOf(1, 2, 3, 4)
val squares = numbers.map { it * it } // [1, 4, 9, 16]

filter()
val numbers = listOf(1, 2, 3, 4)
val evens = numbers.filter { it % 2 == 0 } // [2, 4]

reduce()
val numbers = listOf(1, 2, 3, 4)
val sum = numbers.reduce { acc, n -> acc + n } // 10

fold()
val numbers = listOf(1, 2, 3, 4)
val sum = numbers.fold(0) { acc, n -> acc + n } // 10

forEach()
val numbers = listOf(1, 2, 3, 4)
numbers.forEach { println(it) }

flatMap()
val numbers = listOf(listOf(1, 2), listOf(3, 4))
val flattened = numbers.flatMap { it } // [1, 2, 3, 4]
  • Coroutines
    不同於thread 的os level, 不與其他coroutine 共享記憶體, 發生錯誤不影響其他的coroutines, 更好追蹤race conditions, deadlocks問題, 比AsyncTask更有效處理非同步。
1
2
3
4
5
6
7
8
9
10
11
12
suspend fun getUserData(userId: String): UserData {
return withContext(Dispatchers.IO) {
// perform an expensive I/O operation, such as network call or disk access
// and return the result as a UserData object
}
}

// launch a coroutine to fetch the user data
val job = GlobalScope.launch(Dispatchers.Main) {
val userData = getUserData("123")
// update the UI with the user data
}

時程: 2023/4/21- 2023/4/28


如果你覺得這篇文章很棒,請你不吝點讚 (゚∀゚)

Welcome to my other publishing channels