1: 分屏模式:
專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)南城免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。
該模式可以在手機上使用, 該模式將屏幕一分為二, 同時顯示兩個應(yīng)用界面
2: 畫中畫模式:
該模式主要用于TV, 在該模式下視頻播放的窗口可以一直在最頂端顯示。(視頻小窗口)
3: Freeform模式:
該模式類似于常見的桌面操作系統(tǒng), 應(yīng)用界面的窗口可以自由的拖動和修改大小
1:Manifest 新增屬性:
2: layout 新增屬性:
在freeform模式下定義的默認高度和寬度defaultWidthdefaultHeight, freeform模式下的初始Gravity, freeform模式下最小高度和寬度minWidthdefaultHeight。
3: 多窗口的API:
4: 分屏模式的生命周期:
很明顯, 從上圖的生命周期顯示, 在后臺將應(yīng)用進入分屏模式的時候, 先執(zhí)行destroy()的方法, 即在進入分屏之前, activity會被先銷毀,再調(diào)用onRestoreInstanceState方法恢復(fù)數(shù)據(jù), 回調(diào)onMultiWindowModeChanged()
我們的 APP 進入分屏模式時,在 onMultiWindowModeChanged 方法中如果有對 UI 等的操作,經(jīng)過之后的自動重建就沒有效果了。為了防止這種情況,需要在 AndroidManifest.xml 的 Activity 節(jié)點設(shè)置以下屬性:android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
設(shè)置了這個屬性,在進入分屏模式時,Activity 就不會自動重建了。
5 跨Activity對View的拖拽:
Android 4.0 開始支持activity內(nèi)容的拖拽, 在多窗口的模式下,Android也實現(xiàn)了activity間 實現(xiàn)內(nèi)容的拖拽。在activity間僅限于內(nèi)容的拖拽, 對view的拖拽也是沒辦法實現(xiàn)的 。
類似微信視頻、語音時點擊返回會形成一個App小窗口浮動在界面上,點擊繼續(xù)是通通話,如下圖:
其實實現(xiàn)這個功能只需要你細心分析一下就有思路了:首先這個小窗口是浮動在app最上層的視圖,其次所有觸屏事件需先由該小窗口處理,還有就是小窗口的生命周期和Application也能雖可能不能同生,但是確是可以共死。所以可以在Application中創(chuàng)建一個view添加到WindowManage,這里將視圖為view的window的type設(shè)置成系統(tǒng)級別的窗口,這樣這個window可以在在全局呈現(xiàn)。另外,還需要讓這個window可以隨手指拖動而滑動,手指釋放后會回彈到距離這個釋放點最近的屏幕側(cè)邊,所以需要重寫view 的OnTouch事件。
以上就能實現(xiàn)一個應(yīng)用內(nèi)小窗口了,這里windowManager的布局參數(shù)有坑要踩:
這里主要探討Touchable,F(xiàn)ocusable,OutsideTouchable,TouchModal這四個混合使用的效果。
最簡單的Touchable,
為false,表示窗口不接受觸摸事件;
為true,表示窗口接受觸摸事件;
要窗口接收事件,必須為true。窗口不接受事件,意味著事件會透傳到下一個窗口。這里的窗口事件是指DOWN-UP,窗口是指窗口自身范圍,窗口外的ACTION_OUTSIDE與此設(shè)置無關(guān)。
為false,表示對ACTION_OUTSIDE事件不感興趣。
為true,表示對ACTION_OUTSIDE事件感興趣,此時, 如果新事件被另一個窗口消化 ,則會發(fā)送ACTION_OUTSIDE給該窗口。包括:
2.1. 如果窗口設(shè)置了Touchable為false。即使觸摸事件在窗口內(nèi),由于不處理事件,導(dǎo)致事件透傳,被另一個窗口消化,此時該窗口也會收到ACTION_OUTSIDE。
2.2 觸摸事件在窗口外面觸發(fā),導(dǎo)致事件被另一個窗口消化,此時該窗口也會收到ACTION_OUTSIDE。
2.3 如果窗口設(shè)置了TouchModal和Focusable,導(dǎo)致窗口內(nèi)外的事件被當(dāng)前窗口截獲,由于不是被另一個窗口消化,所以即使設(shè)置了OutsideTouchable,也不會有ACTION_OUTSIDE。
為false,表示不會聚焦,所以不會有軟鍵盤。同時它的z-order可以在軟鍵盤之上,覆蓋軟鍵盤。如果你在不聚焦的情況下,還需要軟鍵盤,可以使用FLAG_ALT_FOCUSABLE_IM來修改。 如果為false,會放棄TouchModal原來的值,強制設(shè)置TouchModal為false
為true,表示窗口可以聚焦。
TouchModal的設(shè)置,只有在Focusable為true時才有效,F(xiàn)ocusable為false,會忽略TouchModal的值
為true,當(dāng)窗口Focusable為true時,無論窗口內(nèi)外,事件都被當(dāng)前窗口接收。
為false,當(dāng)窗口Focusable為true時,只有窗口內(nèi)的事件被當(dāng)前窗口接收。窗口外,OutsideTouchable的設(shè)置決定了是否有ACTION_OUTSIDE事件。
為true,當(dāng)窗口Focusable為false時,設(shè)置不生效。
為false,當(dāng)窗口Focusable為false時,設(shè)置不生效。
FLAG_NOT_TOUCHABLE,意味著,默認是TOUCHABLE,必要時,才使用這個Flag關(guān)閉。
FLAG_NOT_FOCUSABLE,意味著,默認是FOCUSABLE,必要時,才使用這個Flag關(guān)閉。
FLAG_WATCH_OUTSIDE_TOUCH,意味著,默認是不關(guān)心,必要時,才使用這個Flag開啟。
FLAG_NOT_TOUCH_MODAL,意味著,默認是TOUCH_MODAL,必要時,才使用這個Flag關(guān)閉。
FLAG_NOT_FOCUSABLE的注釋是這樣的。This flag will also enable FLAG_NOT_TOUCH_MODAL whether or not that is explicitly set.
所謂的enable,就是使用這個Flag 。直接翻譯就是,使用了FLAG_NOT_FOCUSABLE這個Flag,就會同時使用FLAG_NOT_TOUCH_MODAL這個flag。
使用FLAG_NOT_FOCUSABLE就是關(guān)閉FOCUSABLE,使用FLAG_NOT_TOUCH_MODAL就是關(guān)閉TOUCH_MODAL。簡述就是,關(guān)閉了FOCUSABLE,會同時關(guān)閉TOUCH_MODAL。
比如,Touchable,當(dāng)一個事件確實派發(fā)到窗口到時候,就看這個Flag,為true就是接受事件,為false就是不接受事件。你可以提前截獲不讓事件派發(fā)到窗口,但一旦派發(fā)到窗口,就是這個Flag來決定窗口是否接受事件。
比如,OutsideTouchable,你可以截獲事件不讓事件派發(fā)到另一個窗口,但一旦事件派發(fā)到另一個窗口,就是這個Flag決定當(dāng)前窗口是否接受ACTION_OUTSIDE事件。
以下,窗口內(nèi)外是指,觸點在窗口內(nèi)/外。完整事件是指DOWN to UP事件流。ACTION_OUTSIDE事件只有一次。
總結(jié), Touchable和OutsideTouchable分別控制了窗口內(nèi)外的事件 。
總結(jié), 當(dāng)且僅當(dāng)Focusable為true,TouchModal為true情況下,窗口內(nèi)外事件才被當(dāng)前窗口截獲;否則,都是窗口內(nèi)才有完整事件,窗口外才有ACTION_OUTSIDE事件 。
Activity是一個 界面 的載體,可以把它與html頁面進行類比,html頁面由各種各樣的標(biāo)簽組成,而Activity則可以由 各種控件 組成。
Activity的掌握重點主要在于:
a.Activity的生命周期?
b.Activity的啟動模式
? ? ? ? onCreate() :?
當(dāng)Activity第一次被創(chuàng)建的時候調(diào)用此方法.一般在此方法中 進行控件的聲明,添加事件等初始化工作 .
onStart():
當(dāng)Activity被顯示到屏幕上的時候調(diào)用此方法,執(zhí)行完此方法后 界面可見
onResume():
當(dāng)此Activity能夠被操作之前,也就是能夠獲得用戶的焦點之前調(diào)用此方法.
onRestart():
當(dāng)Activity被停止后又被再次啟動之前調(diào)用此方法.接著將調(diào)用onStart()方法.
onPause():
當(dāng)?shù)谝粋€Activity通過Intent啟動第二個Activity的時候,將調(diào)用第一個Activity的onPause()方法.然后調(diào)用第二個Activity的onCreate(),onStart(),onResume()方法,接著調(diào)用第一個Activity的onStop()方法.如果Activity重新獲得焦點,則將調(diào)用onResume()方法;如果此Activity進入用戶不可見狀態(tài),那么將調(diào)用onStop()方法.
onStop():
當(dāng)?shù)谝粋€Activity被第二個Activity完全覆蓋,或者被銷毀的時候回調(diào)用此方法.如果此Activity還會與用戶進行交互,將調(diào)用onRestart方法();如果此Activity將被銷毀,那么將調(diào)用onDestroy()方法.
? ???? ?注意:
a.home鍵返回,鎖屏,關(guān)閉界面肯定會調(diào)用onStop方法
b.但是開啟另一個Activity并不一定會調(diào)用onStop方法
onDestroy():
? ? ? ? ? ?Activity被銷毀之前調(diào)用此方法.或者是調(diào)用finish()方法結(jié)束Activity的時候調(diào)用此方法.可以在此方法中進行收尾工作,比如釋放資源等.
??? Active/Runing 一個新 Activity 啟動入棧后,它在屏幕最前端,處于棧的最頂端,此時它處于可見并可和用戶交互的激活狀態(tài)。
??? Paused ?當(dāng) Activity 被另一個透明或者 Dialog 樣式的 Activity 覆蓋時的狀態(tài)。此時它依然與窗口管理器保持連接,系統(tǒng)繼續(xù)維護其內(nèi)部狀態(tài),所以它仍然可見,但它已經(jīng)失去了焦點故不可與用戶交互。
??? Stoped ?當(dāng) Activity 被另外一個 Activity 覆蓋、失去焦點并不可見時處于? Stop ed 狀態(tài)。
??? Killed ?Activity 被系統(tǒng)殺死回收或者沒有被啟動時處于? Killed 狀態(tài)。
在 manifest 文件中聲明 activity 時,利用activity元素的 launchMode 屬性來設(shè)定 activity 與 task 的關(guān)系。
launchMode?屬性 指明了 activity 啟動 task 的方式,默認 standard方式
??? standard(默認模式):
? ? 系統(tǒng)在啟動 activity 的 task 中創(chuàng)建一個新的 activity 實例,并把 intent 傳送路徑指向它。 該 activity 可以被實例化多次,各個實例可以屬于不同的 task,一個 task 中也可以存在多個實例。
??? singleTop:
? ? ?如果 activity 已經(jīng)存在一個實例并位于當(dāng)前 task 的 棧頂 ,則系統(tǒng)會調(diào)用已有實例的 onNewIntent() 方法把 intent 傳遞給已有實例,而不是創(chuàng)建一個新的 activity 實例。activity 可以被實例化多次,各個實例可以屬于不同的 task,一個 task 中可以存在多個實例(但僅當(dāng) back stack 頂?shù)?activity 實例不是該 activity 的)。
? ?? singleTask:
系統(tǒng)將創(chuàng)建一個新的 task,并把 activity 實例 作為根 放入其中。但是,如果 activity 已經(jīng)在其它 task 中存在實例,則系統(tǒng)會通過調(diào)用其實例的onNewIntent()?方法把 intent 傳給已有實例,而不是再創(chuàng)建一個新實例。 此 activity 同一時刻只能存在一個實例。
例如:可以用于關(guān)閉所有Activity或重新登錄等
singleInstance:
除了系統(tǒng)不會把其它 activity 放入當(dāng)前實例所在的 task 之外,其它均與"singleTask"相同。activity 總是它所在 task 的唯一成員;它所啟動的任何 activity 都會放入其它 task 中
主要是startActivity(intent),或者帶值返回startActivityForResult(intent)?, Activity的跳轉(zhuǎn)方式? 。
1、ViewRoot 對應(yīng)于 ViewRootImpl 類,它是連接 WindowManager 和 DecorView 的紐帶,View 的三大流程均是通過 ViewRoot 來完成的。在 ActivityThread 中,當(dāng) Activity 對象被創(chuàng)建完畢后,會將 DecorView 添加到 Window 中,同時會創(chuàng)建 ViewRootImpl 對象,并將 ViewRootImpl 對象和 DecorView 建立關(guān)聯(lián)
2、 自定義View-繪制流程概述
4、 Android Handler
6、 Android Bitmap
2、MeasureSpec:
3、一般來說,使用多進程會造成以下幾個方面的問題:
5、Window 概念與分類:
Window 是一個抽象類,它的具體實現(xiàn)是 PhoneWindow。WindowManager 是外界訪問 Window 的入口,Window 的具體實現(xiàn)位于 WindowManagerService 中,WindowManager 和 WindowManagerService 的交互是一個 IPC 過程。Android 中所有的視圖都是通過 Window 來呈現(xiàn),因此 Window 實際是 View 的直接管理者。
6、window的三大操作:addView、upView、removeView
7、 Bitmap 中有兩個內(nèi)部枚舉類:
保存圖片資源:
圖片壓縮:
基本使用:
8、Context 本身是一個抽象類,是對一系列系統(tǒng)服務(wù)接口的封裝,包括:內(nèi)部資源、包、類加載、I/O操作、權(quán)限、主線程、IPC 和組件啟動等操作的管理。ContextImpl, Activity, Service, Application 這些都是 Context 的直接或間接子類
9、SharedPreferences 采用key-value(鍵值對)形式, 主要用于輕量級的數(shù)據(jù)存儲, 尤其適合保存應(yīng)用的配置參數(shù), 但不建議使用 SharedPreferences 來存儲大規(guī)模的數(shù)據(jù), 可能會降低性能
10、SharedPreferences源碼有用synchronize進行加鎖同步
11、Handler 有兩個主要用途:
(1)安排 Message 和 runnables 在將來的某個時刻執(zhí)行;
(2)將要在不同于自己的線程上執(zhí)行的操作排入隊列。(在多個線程并發(fā)更新UI的同時保證線程安全。)
只有主線程能對UI進行操作,所以在對UI進行跟改之前,ViewRootImpl 對UI操作做了驗證,這個驗證工作是由 ViewRootImpl的 checkThread 方法完成:
12、ThreadLocal 是一個線程內(nèi)部的數(shù)據(jù)存儲類,通過它可以在指定的線程中存儲數(shù)據(jù),其他線程則無法獲取。Looper、ActivityThread 以及 AMS 中都用到了 ThreadLocal。當(dāng)不同線程訪問同一個ThreadLocal 的 get方法,ThreadLocal 內(nèi)部會從各自的線程中取出一個數(shù)組,然后再從數(shù)組中根據(jù)當(dāng)前 ThreadLcoal 的索引去查找對應(yīng)的value值:
13、Android 提供了幾種途徑來從其他線程訪問 UI 線程:
Android單線程模式必須遵守的規(guī)則:
14、HandlerThread 集成了 Thread,卻和普通的 Thread 有顯著的不同。普通的 Thread 主要用于在 run 方法中執(zhí)行一個耗時任務(wù),而 HandlerThread 在內(nèi)部創(chuàng)建了消息隊列,外界需要通過 Handler 的消息方式通知 HanderThread 執(zhí)行一個具體的任務(wù)。
15、IntentService 可用于執(zhí)行后臺耗時的任務(wù),當(dāng)任務(wù)執(zhí)行后會自動停止,由于其是 Service 的原因,它的優(yōu)先級比單純的線程要高,所以 IntentService 適合執(zhí)行一些高優(yōu)先級的后臺任務(wù)。在實現(xiàn)上,IntentService 封裝了 HandlerThread 和 Handler。IntentService 第一次啟動時,會在 onCreatea 方法中創(chuàng)建一個 HandlerThread,然后使用的 Looper 來構(gòu)造一個 Handler 對象 mServiceHandler,這樣通過 mServiceHandler 發(fā)送的消息最終都會在 HandlerThread 中執(zhí)行。每次啟動 IntentService,它的 onStartCommand 方法就會調(diào)用一次,onStartCommand 中處理每個后臺任務(wù)的 Intent,onStartCommand 調(diào)用了 onStart 方法。可以看出,IntentService 僅僅是通過 mServiceHandler 發(fā)送了一個消息,這個消息會在 HandlerThread 中被處理。mServiceHandler 收到消息后,會將 Intent 對象傳遞給 onHandlerIntent 方法中處理,執(zhí)行結(jié)束后,通過 stopSelf(int startId) 來嘗試停止服務(wù)。(stopSelf() 會立即停止服務(wù),而 stopSelf(int startId) 則會等待所有的消息都處理完畢后才終止服務(wù))。
16、RecyclerView 優(yōu)化