Android 小知識點記錄(二)

1.關於十進制移動上篇裏說過,加強理解此處再粘貼一個例子:
(((oxf0ff&0x000f)|0x00f0)<<1)/(4>>1) = 255 即 0x00ff

                                                                                      // f0ff
        int i = 0xF0FF & 0x000F;                       // 0x000F   十六進制下也可以用   // 000f  的方式豎向計算.因爲換成二進制之後..只不過是向左移動了四位.運算模式和規則沒變.結果不變
        int i1 = i | 0x00F0;                           // 0x00FF
        int i2 = i1 << 1 / 2;                          // 0x00FF   移位符號永遠是相對於二進制來說. 不能理解成在十六進制下的移位置運算
        Log.d("fssssss", "onCreate: "+i2);

        int i3 = 0x0F0 >>  1;   //120
        Log.d("fsssssssss", "onCreate: "+i3);
  1. 關於啓動模式:
    使用Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP時調用了onNewIntent方法,複用了MainActivity,說明他們可以實現和singleTask一樣的效果

Intent.FLAG_ACTIVITY_CLEAR_TOP 不等同於singleTask 啓動模式,因爲不會調用onNewIntent

3.能用思考和分析規避的的問題,避免用體力和bug 去嘗試

  1. 裝飾者和代理模式很像,只是結構上,但是功能上代理是爲了訪問控制(訪問被代理 對象) 裝飾者是爲了增強功能

5.關於postInvalidate() requestLayout()
requestLayout() 只是通知父容器位置變化,重新進行measure 和layout 不會重新繪製ondraw
postInvalidate() 不關心位置變化,不走measure 和layout 只走ondraw

  1. SharePreferance 是否是線程安全的?
    SharedPreferences是線程安全的,它的內部實現使用了大量synchronized關鍵字SharedPreferences不是進程安全的第一次調用getSharedPreferences會加載磁盤 xml 文件(這個加載過程是異步的,通過new Thread來執行,所以並不會在構造SharedPreferences的時候阻塞線程,但是會阻塞getXxx/putXxx/remove/clear等調用),但後續調用getSharedPreferences會從內存緩存中獲取。 如果第一次調用getSharedPreferences時還沒從磁盤加載完畢就馬上調用 getXxx/putXxx, 那麼getXxx/putXxx操作會阻塞,直到從磁盤加載數據完成後才返回所有的getXxx都是從內存中取的數據,數據來源於SharedPreferences.mMapapply同步回寫(commitToMemory())內存SharedPreferences.mMap,然後把異步回寫磁盤的任務放到一個單線程的線程池隊列中等待調度。apply不需要等待寫入磁盤完成,而是馬上返回commit同步回寫(commitToMemory())內存SharedPreferences.mMap,然後如果mDiskWritesInFlight(此時需要將數據寫入磁盤,但還未處理或未處理完成的次數)的值等於1,那麼直接在調用commit的線程執行回寫磁盤的操作,否則把異步回寫磁盤的任務放到一個單線程的線程池隊列中等待調度。commit會阻塞調用線程,知道寫入磁盤完成才返回MODE_MULTI_PROCESS是在每次getSharedPreferences時檢查磁盤上配置文件上次修改時間和文件大小,一旦所有修改則會重新從磁盤加載文件,所以並不能保證多進程數據的實時同步從 Android N 開始,,不支持MODE_WORLD_READABLE & MODE_WORLD_WRITEABLE。一旦指定, 直接拋異常

  2. 方法時間性能優化
    android.os.Debug.startMethodTracing(String traceName);
    android.os.Debug.stopMethodTracing();


8.關於切換語言 導致棧內activity 重新創建的問題
如果棧裏有兩個activity 如果切換語言導致界面重新創建 , 則兩個activity 創建時間是不同的,系統只會在activity 變爲可見的時候重新創建,如果在A1 oncreate 中啓動了A2 A1 onActivityResult 中finish() A1
那麼 棧內A1 A2 的情況下,切換語言,a2 finish 生命週期如下
A1 onDestroy A1onCreate (先重新創建)
A1onActivityResult (中執行finish)
A2 onCreate (由此可見,是A2 先創建,爲了resume 做好準備之後A1才銷燬的)
A1 stop destory
A2 resume()

9.HTTP 和HTTPS



  1. tcp 三次握手四次揮手 http://www.cnblogs.com/zmlctt/p/3690998.html

1.爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?

這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的連接請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可能未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的。

2.爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到CLOSED狀態?

這個問題可以參考《unix 網絡編程》(第三版,2.7 TIME_WAIT狀態)。

TIME_WAIT狀態由兩個存在的理由。

(1)可靠的實現TCP全雙工鏈接的終止。

這是因爲雖然雙方都同意關閉連接了,而且握手的4個報文也都協調和發送完畢,按理可以直接回到CLOSED狀態(就好比從SYN_SEND狀態到ESTABLISH狀態那樣);但是因爲我們必須要假想網絡是不可靠的,你無法保證你最後發送的ACK報文會一定被對方收到,因此對方處於LAST_ACK狀態下的SOCKET可能會因爲超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT狀態的作用就是用來重發可能丟失的ACK報文。

(2)允許老的重複的分節在網絡中消逝。

假 設在12.106.32.254的1500端口和206.168.1.112.219的21端口之間有一個TCP連接。我們關閉這個鏈接,過一段時間後在 相同的IP地址和端口建立另一個連接。後一個鏈接成爲前一個的化身。因爲它們的IP地址和端口號都相同。TCP必須防止來自某一個連接的老的重複分組在連 接已經終止後再現,從而被誤解成屬於同一鏈接的某一個某一個新的化身。爲做到這一點,TCP將不給處於TIME_WAIT狀態的鏈接發起新的化身。既然 TIME_WAIT狀態的持續時間是MSL的2倍,這就足以讓某個方向上的分組最多存活msl秒即被丟棄,另一個方向上的應答最多存活msl秒也被丟棄。 通過實施這個規則,我們就能保證每成功建立一個TCP連接時。來自該鏈接先前化身的重複分組都已經在網絡中消逝了。

  1. 爲什麼不能用兩次握手進行連接?

1.爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?

這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的連接請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可能未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的。
2.爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到CLOSED狀態?

這個問題可以參考《unix 網絡編程》(第三版,2.7 TIME_WAIT狀態)。

TIME_WAIT狀態由兩個存在的理由。

(1)可靠的實現TCP全雙工鏈接的終止。

這是因爲雖然雙方都同意關閉連接了,而且握手的4個報文也都協調和發送完畢,按理可以直接回到CLOSED狀態(就好比從SYN_SEND狀態到ESTABLISH狀態那樣);但是因爲我們必須要假想網絡是不可靠的,你無法保證你最後發送的ACK報文會一定被對方收到,因此對方處於LAST_ACK狀態下的SOCKET可能會因爲超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT狀態的作用就是用來重發可能丟失的ACK報文。

(2)允許老的重複的分節在網絡中消逝。

假 設在12.106.32.254的1500端口和206.168.1.112.219的21端口之間有一個TCP連接。我們關閉這個鏈接,過一段時間後在 相同的IP地址和端口建立另一個連接。後一個鏈接成爲前一個的化身。因爲它們的IP地址和端口號都相同。TCP必須防止來自某一個連接的老的重複分組在連 接已經終止後再現,從而被誤解成屬於同一鏈接的某一個某一個新的化身。爲做到這一點,TCP將不給處於TIME_WAIT狀態的鏈接發起新的化身。既然 TIME_WAIT狀態的持續時間是MSL的2倍,這就足以讓某個方向上的分組最多存活msl秒即被丟棄,另一個方向上的應答最多存活msl秒也被丟棄。 通過實施這個規則,我們就能保證每成功建立一個TCP連接時。來自該鏈接先前化身的重複分組都已經在網絡中消逝了。

  1. 爲什麼不能用兩次握手進行連接?

我們知道,3次握手完成兩個重要的功能,既要雙方做好發送數據的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。
現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作爲例子,考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認爲連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認爲連接還未建立成功,將忽略S發來的任何數據分 組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章