遇到的問題

Classloader執(zhí)行流程

1.線程和協(xié)程的區(qū)別

線程(Thread):

線程是操作系統(tǒng)能夠進行運算調度的最小單位踱卵。它被包含在進程之中,是進程中的實際運作單位郑临。

每個線程可以獨立執(zhí)行栖博,有自己的調用堆棧和局部變量。

線程間的切換由操作系統(tǒng)內(nèi)核管理厢洞,涉及到上下文切換的成本仇让,包括保存和加載不同線程的狀態(tài)。

線程適用于執(zhí)行長時間的計算密集型任務犀变。

協(xié)程(Coroutine):

協(xié)程是一種輕量級的線程妹孙。它們通過協(xié)作而非搶占式的方式進行切換,即協(xié)程需要顯式地進行切換获枝。

協(xié)程運行在單個線程中蠢正,因此不需要多線程的同步機制,如鎖省店,這減少了開銷嚣崭。

協(xié)程提供了非常有效的異步編程模型笨触,可以在等待操作(如 I/O)完成時掛起,這樣可以處理大量并發(fā)的操作而不占用多個線程雹舀。

區(qū)別

1. 調度方式

線程:由操作系統(tǒng)內(nèi)核進行調度和管理芦劣,線程的切換需要內(nèi)核介入,開銷較大说榆。

協(xié)程:由用戶態(tài)的調度器進行調度虚吟,協(xié)程的切換在用戶態(tài)完成,開銷較小签财。

2. 資源消耗

線程:每個線程都需要獨立的棿浚空間和內(nèi)核資源,線程數(shù)量受到系統(tǒng)限制唱蒸。

協(xié)程:協(xié)程共享線程的棸铞辏空間,資源消耗較小神汹,可以在一個線程中運行成千上萬個協(xié)程庆捺。

3. 編程模型

線程:編程模型相對復雜,需要處理線程同步屁魏、死鎖等問題滔以。

協(xié)程:編程模型簡單,通過掛起和恢復操作實現(xiàn)協(xié)作式多任務處理蚁堤,避免了復雜的同步問題醉者。

4. 并發(fā)性

線程:真正的并行執(zhí)行,適合計算密集型任務披诗,CPU密集型任務撬即。

協(xié)程:協(xié)作式并發(fā),適合I/O密集型任務呈队,通過主動讓出CPU實現(xiàn)并發(fā)剥槐。

5. 控制權

線程:操作系統(tǒng)控制線程的執(zhí)行和調度。

協(xié)程:程序員控制協(xié)程的執(zhí)行流程宪摧,通過顯式的掛起和恢復操作進行調度粒竖。


2.kotlin和Java的對比

(1)代碼量:kotlin比Java代碼量少很多。kotlin通過使用簡潔的語法和函數(shù)式編程的概念來簡化java代碼几于,減少代碼的復雜性蕊苗。

(2)空指針安全:kotlin 通過引入空指針安全機制來避免空指針異常,而Java需要手動檢查null值沿彭。

(3)擴展函數(shù):kotlin中有一個強大的功能叫擴展函數(shù)朽砰,它允許用戶將一個已存在的類進行擴展

(4)函數(shù)式編程概念:kotlin 支持更多的函數(shù)式編程概念,比如lambda表達式、高階函數(shù)等

(5)數(shù)據(jù)類:kotlin 中引入了數(shù)據(jù)類瞧柔,它允許程序員快速創(chuàng)建簡單的數(shù)據(jù)類漆弄,這些數(shù)據(jù)類型可以自動生成一些有用的方法,如equals造锅、hashCode撼唾、toString等。這使得開發(fā)人員可以更快地創(chuàng)建和使用自定義數(shù)據(jù)類型哥蔚。倒谷。相比之下Java需要編寫大量的樣板代碼

(6)類型推斷

類型推斷是Kotlin的一個核心概念,它允許開發(fā)人員在聲明變量時不需要指定變量的類型糙箍,而是由編譯器根據(jù)變量的值自動推斷出變量的類型恨锚。這使得Kotlin的代碼更簡潔,更易于閱讀和維護倍靡。

總的來說kotlin 相對于Java擁有更簡潔的語法,更多的功能和更高的生產(chǎn)效率课舍,但是Java擁有更成熟的生態(tài)塌西,更廣泛的支持和更好的跨平臺支持。

(7)委托

委托是Kotlin的一個核心概念筝尾,它允許開發(fā)人員在一個類型上委托給另一個類型的屬性和方法捡需。這使得開發(fā)人員可以在不修改原始類型的情況下,為其添加新的功能筹淫。


擴展函數(shù)示例:

在 Kotlin 中站辉,擴展函數(shù)是一種非常有用的特性,它允許你為不屬于自己的類添加新的方法损姜。這在很多情況下非常有用饰剥,例如為標準庫中的類(如 String、List 等)添加額外的功能摧阅,或者給第三方庫的類添加功能汰蓉。

定義擴展函數(shù)

要定義一個擴展函數(shù),你需要使用 fun 關鍵字棒卷,后面跟著接收者類型(即你想要擴展的類)顾孽,然后是這個類型后面的點(.),接著是函數(shù)名和參數(shù)列表比规。

1若厚、示例:為 String 類添加一個擴展函數(shù)

fun String.capitalizeFirstLetter(): String {

? ? return this.substring(0, 1).toUpperCase() + this.substring(1)

}

在這個例子中,capitalizeFirstLetter 是為 String 類型添加的擴展函數(shù)蜒什。你可以像調用普通成員函數(shù)一樣調用它

val myString = "hello"

println(myString.capitalizeFirstLetter())? // 輸出 "Hello"

擴展函數(shù)與成員函數(shù)的區(qū)別

調用方式:擴展函數(shù)使用點符號(.)調用测秸,而成員函數(shù)直接通過對象調用。

可見性:擴展函數(shù)不能訪問接收者的私有成員框仔。成員函數(shù)可以訪問類的私有成員咳榜。

靜態(tài)分發(fā):擴展函數(shù)是靜態(tài)分派的,而成員函數(shù)是動態(tài)分派的(在運行時根據(jù)對象實際類型調用方法)实抡。

示例:為 List 添加擴展函數(shù)來計算總和

fun <T> List<T>.sumByInt(selector: (T) -> Int): Int {

? ? var sum = 0

? ? for (item in this) {

? ? ? ? sum += selector(item)

? ? }

? ? return sum

}

在這個例子中肃晚,sumByInt 是一個泛型擴展函數(shù)锚贱,用于對列表中的元素應用一個轉換函數(shù),并返回所有轉換結果的總和关串。

val numbers = listOf(1, 2, 3, 4)

println(numbers.sumByInt { it })? // 輸出 10

注意事項

命名沖突:如果你定義了一個與已有類的成員函數(shù)同名的擴展函數(shù)拧廊,那么在調用時將調用擴展函數(shù)而不是成員函數(shù)〗蓿可以通過使用導入限定符(如 String.capitalizeFirstLetter())來明確指定使用哪個函數(shù)吧碾。

性能考慮:雖然擴展函數(shù)很有用,但它們是通過代理對象實現(xiàn)的墓卦,這可能會帶來一些性能開銷倦春。在性能敏感的代碼中,應謹慎使用落剪。

擴展函數(shù)是 Kotlin 中一個強大且靈活的特性睁本,可以極大地增加代碼的可讀性和復用性。

數(shù)據(jù)類

數(shù)據(jù)類的一個例子是下面的代碼:

data class Person(val name:String,val age:Int)

fun main(args:Array<String>){

val person1=Person("Alice",30)

val person2=Person("Bob",25)

println(person1==person2)// false

println(person1.hashCode())// 123

println(person1.toString())// Person(name=Alice, age=30)}

在這個例子中忠怖,Person是一個數(shù)據(jù)類呢堰,它有兩個屬性:name和age。由于Person是一個數(shù)據(jù)類凡泣,編譯器會自動生成一些有用的方法枉疼,如equals、hashCode和toString鞋拟。我們可以直接在Person類型上調用這些方法骂维,而無需手動實現(xiàn)它們。

委托的一個例子:

class DelegatingClass(private val delegate):Any{

operatorfunget(property:KProperty<*>)=delegate.get(property)

operatorfunset(property:KProperty<*>,value:Any)=delegate.set(property,value)

}

fun main(args:Array<String>){

val delegate=object: Any(){

val name="Alice"

val age=30

}

val delegatingClass=DelegatingClass(delegate)

println(delegatingClass.name)// Alice

println(delegatingClass.age)// 30

}

在這個例子中贺纲,DelegatingClass是一個委托類席舍,它在構造函數(shù)中接受一個delegate參數(shù)。DelegatingClass實現(xiàn)了get和set操作符哮笆,這使得它可以委托給delegate的屬性和方法来颤。我們可以直接在DelegatingClass類型上調用name和age屬性,而無需手動實現(xiàn)它們稠肘。

3.多線程訪問修改list怎么保證數(shù)據(jù)安全

Android 中l(wèi)ist是線程不安全的福铅,意味著在多線程中同時訪問和修改list時,可能會導致不確定的結果和數(shù)據(jù)不一致性项阴。為了確保list的線程安全滑黔,可以采用以下方式

(1)使用同步集合類

? ? ? ? ? ? 在多線程環(huán)境下笆包,使用同步集合類保證list的線程安全性,Android 提供了Collections.synchronizedList()方法

? ? ? ? ? ? 例如:LIst<String> list = new ArrayList();

? ? ? ? ? ? List<String> synchronizedList = Collections.synchronizedList(list);

操作時還是需要手動進行同步

synchronized(list) {

}

(2) 使用并發(fā)集合類

? ? CopyOnWriteArrayList<String> concurrentList = new CopyOnWriteArrayList();

(3) 使用鎖機制 來保證list的線程安全性略荡, 可以使用 ReentrantLock 或者synchronized關鍵字來實現(xiàn)互斥訪問庵佣。

使用 synchronized 關鍵字
List<String> list = new ArrayList<>();

public void addElement(String element) {

? ? synchronized (list) {

? ? ? ? list.add(element);

? ? }

}

public String getElement(int index) {

? ? synchronized (list) {

? ? ? ? return list.get(index);

? ? }

}

使用 ReentrantLock

List<String> list = new ArrayList<>();

private final ReentrantLock lock = new ReentrantLock();

public void addElement(String element) {

? ? lock.lock();

? ? try {

? ? ? ? list.add(element);

? ? } finally {

? ? ? ? lock.unlock();

? ? }

}

public String getElement(int index) {

? ? lock.lock();

? ? try {

? ? ? ? return list.get(index);

? ? } finally {

? ? ? ? lock.unlock();

? ? }

}


4.okhttp攔截器

addInterceptor和addNetworkInterceptor

選擇使用 addInterceptor 還是 addNetworkInterceptor 時,取決于你希望攔截的網(wǎng)絡層級汛兜。

addInterceptor

方法用于攔截應用層級的請求和響應巴粪。這意味著它可以訪問應用程序發(fā)送的請求和服務器返回的響應,但不能訪問底層的網(wǎng)絡傳輸細節(jié)粥谬。通常情況下肛根,這足以滿足大多數(shù)的需求,比如添加身份驗證漏策、修改請求頭等派哲。

addNetworkInterceptor

方法用于攔截網(wǎng)絡層級的請求和響應。這意味著它可以訪問底層的網(wǎng)絡傳輸細節(jié)掺喻,包括請求和響應的字節(jié)流芭届。它可以用于監(jiān)視網(wǎng)絡流量、修改網(wǎng)絡傳輸行為或進行緩存控制感耙。但要注意喉脖,addNetworkInterceptor 方法不會攔截從緩存中提供的響應。

根據(jù)你的需求抑月,選擇適合的攔截器方法。如果你只需要訪問應用層級的請求和響應舆蝴,一般情況下使用 addInterceptor 就足夠了谦絮。如果你需要對網(wǎng)絡層級進行更深入的控制,可以使用 addNetworkInterceptor洁仗。需要注意的是层皱,在使用 addNetworkInterceptor 時,要謹慎處理請求和響應的字節(jié)流赠潦,以免引起潛在的問題叫胖。

時機

addInterceptor 和 addNetworkInterceptor 方法添加的攔截器在 OkHttp 中的調用時機略有不同:

addInterceptor 方法添加的攔截器在應用層級的調用時機是在請求發(fā)出后、服務器響應之前她奥。它會被應用于所有的網(wǎng)絡請求瓮增,包括重定向和重試的請求。在請求鏈中哩俭,每個攔截器的 intercept 方法會按照添加的順序依次被調用绷跑。

addNetworkInterceptor 方法添加的攔截器在網(wǎng)絡層級的調用時機是在請求發(fā)出后、服務器響應之前凡资,并且只會被調用一次砸捏。它可以訪問到底層的網(wǎng)絡傳輸細節(jié),如請求和響應的字節(jié)流。然而垦藏,addNetworkInterceptor 方法不會攔截從緩存中提供的響應梆暖。


5.點擊按鈕的事件分發(fā)

Android 的事件分發(fā)機制主要包括以下幾個步驟:

事件生成:用戶在設備上進行觸摸、滑動等操作時掂骏,系統(tǒng)會生成相應的事件轰驳,如觸摸事件(MotionEvent)。

事件發(fā)送:生成的事件會被發(fā)送到當前活動(Activity)或視圖(View)樹的根節(jié)點芭挽。

事件分發(fā):

Activity:首先滑废,事件會被傳遞給活動的 dispatchTouchEvent() 方法。這個方法決定如何將事件進一步分發(fā)袜爪。

ViewGroup:如果當前活動包含 ViewGroup(如 LinearLayout蠕趁、RelativeLayout 等),dispatchTouchEvent() 會先調用 ViewGroup 的 onInterceptTouchEvent() 方法辛馆。如果返回 true俺陋,則 ViewGroup 會處理事件;如果返回 false昙篙,則將事件傳遞給子視圖腊状。

View:對于普通的視圖(View),會調用其 onTouchEvent() 方法來處理事件苔可。

事件處理:

onTouchEvent():當視圖接收到事件后缴挖,會根據(jù)事件的類型(如按下、移動焚辅、抬起等)在此方法中處理相應的邏輯映屋。

事件處理過程可能涉及多個視圖,尤其是在有嵌套的視圖結構中同蜻。

事件消費:如果某個視圖處理了事件(返回 true)棚点,后續(xù)的視圖將不會再接收到這個事件。如果沒有視圖消費事件湾蔓,事件將向上傳遞瘫析,直到達到活動。

最終結果:處理完成后默责,結果可能會影響用戶界面的狀態(tài)或行為贬循。

注意事項:

onInterceptTouchEvent():在 ViewGroup 中使用,決定是否攔截子視圖的事件桃序。

事件的傳遞順序:從上到下(Activity → ViewGroup → View)甘有,處理順序是從下到上(View → ViewGroup → Activity)。


事件傳遞的對象:

事件在 Android 中主要在 Activity葡缰、ViewGroup 和 View 之間傳遞亏掀。

Activity 作為應用的入口忱反,首先接收事件;ViewGroup 可能根據(jù)需要攔截事件滤愕,而具體的 View 則負責執(zhí)行實際的事件處理温算。這種多層次的傳遞機制保證了事件處理的靈活性和精確性。

事件分發(fā)順序

Activity:當用戶觸摸屏幕時间影,事件首先被發(fā)送到當前的 Activity注竿。Activity 會調用其 dispatchTouchEvent() 方法,決定事件的后續(xù)處理魂贬。

ViewGroup:如果 Activity 的 dispatchTouchEvent() 方法未攔截事件巩割,事件將傳遞到 ViewGroup。ViewGroup 會執(zhí)行 onInterceptTouchEvent() 方法付燥,判斷是否攔截該事件宣谈。如果返回 true,則事件會在 ViewGroup 中處理键科;如果返回 false闻丑,事件會繼續(xù)傳遞到子視圖。

View:最終勋颖,事件將傳遞到具體的 View嗦嗡,在 View 中調用 onTouchEvent() 方法來處理事件。視圖可以根據(jù)事件的類型(如點擊饭玲、滑動等)執(zhí)行相應的邏輯侥祭。

事件分發(fā)過程中的方法

dispatchTouchEvent():

作用:負責分發(fā)觸摸事件。

調用時刻:當 Activity 或 ViewGroup 收到觸摸事件時首先調用茄厘。它決定事件是否繼續(xù)傳遞給子視圖或直接處理矮冬。

onInterceptTouchEvent():

作用:用于判斷 ViewGroup 是否攔截事件。

調用時刻:在 ViewGroup 的 dispatchTouchEvent() 內(nèi)部調用蚕断。通常用于處理復雜的觸摸交互,比如滑動或拖動入挣。

onTouchEvent():

作用:處理具體的觸摸事件亿乳。

調用時刻:在 dispatchTouchEvent() 內(nèi)部調用。用于執(zhí)行視圖的響應邏輯径筏,比如狀態(tài)更新葛假、動畫觸發(fā)等。


6滋恬、線程鎖

在Android應用程序中聊训,線程鎖是用于實現(xiàn)多線程同步和防止競爭條件(race condition)的重要工具。線程鎖通常用于確保在多個線程之間對共享資源的訪問進行協(xié)調恢氯,以避免并發(fā)問題带斑。

以下是Android中線程鎖的一些常見形式:

1.同步塊(Synchronized Blocks):

使用 synchronized 關鍵字可以創(chuàng)建同步塊鼓寺,確保只有一個線程可以進入同步塊內(nèi)部的代碼段。這通常用于保護共享資源勋磕,以防止多個線程同時訪問妈候。

例如:

synchronized(lockObject){// 同步的代碼塊}

2.同步方法(Synchronized Methods):

在方法聲明中使用 synchronized 關鍵字,將整個方法標記為同步挂滓。這使得只有一個線程可以同時訪問這個方法苦银。

例如:

publicsynchronizedvoidmySynchronizedMethod(){// 同步的方法體}

3.ReentrantLock:

ReentrantLock 是Java中的一個高級鎖機制,允許更靈活的鎖控制赶站。與 synchronized 不同幔虏,ReentrantLock 允許可中斷的鎖、超時的鎖等贝椿。

例如:

Locklock=newReentrantLock();lock.lock();// 獲得鎖try{// 同步的代碼塊}finally{lock.unlock();// 釋放鎖}

4.Condition:

Condition 是與 ReentrantLock 一起使用的想括,用于線程等待和通知。它可以用于創(chuàng)建更復雜的線程同步方案团秽,如生產(chǎn)者-消費者問題主胧。

例如:

Locklock=newReentrantLock();

Conditioncondition=lock.newCondition();

// 等待條件

condition.await();

// 通知條件

condition.signal();

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市习勤,隨后出現(xiàn)的幾起案子踪栋,更是在濱河造成了極大的恐慌图毕,老刑警劉巖夷都,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件予颤,死亡現(xiàn)場離奇詭異,居然都是意外死亡蛤虐,警方通過查閱死者的電腦和手機党饮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驳庭,“玉大人,你說我怎么就攤上這事饲常。” “怎么了贝淤?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵柒竞,是天一觀的道長。 經(jīng)常有香客問我播聪,道長布隔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任执泰,我火速辦了婚禮渡蜻,結果婚禮上,老公的妹妹穿的比我還像新娘茸苇。我一直安慰自己,他們只是感情好学密,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腻暮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哭靖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天筝蚕,我揣著相機與錄音,去河邊找鬼起宽。 笑死,一個胖子當著我的面吹牛坯沪,可吹牛的內(nèi)容都是我干的擒滑。 我是一名探鬼主播腐晾,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼橘忱,長吁一口氣:“原來是場噩夢啊……” “哼卸奉!你這毒婦竟也來了?” 一聲冷哼從身側響起榄棵,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凝颇,失蹤者是張志新(化名)和其女友劉穎潘拱,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拧略,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡芦岂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了垫蛆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡川无,死狀恐怖虑乖,靈堂內(nèi)的尸體忽然破棺而出懦趋,到底是詐尸還是另有隱情疹味,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布诫咱,位于F島的核電站,受9級特大地震影響遂跟,放射性物質發(fā)生泄漏婴渡。R本人自食惡果不足惜幻锁,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一哄尔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岭接,春花似錦臼予、人聲如沸鸣戴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽入偷。三九已至追驴,卻和暖如春疏之,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锋爪。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留河泳,地道東北人年栓。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像某抓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子否副,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容