Android基礎知識

Activity生命周期郑藏。
  • 啟動Activity: onCreate()—>onStart()—>onResume()确徙,Activity進入運行狀態(tài)镇饺。

  • Activity退居后臺: 當前Activity轉(zhuǎn)到新的Activity界面或按Home鍵回到主屏: onPause()—>onStop()愿卸,進入停滯狀態(tài)抄瓦。

  • Activity返回前臺: onRestart()—>onStart()—>onResume(),再次回到運行狀態(tài)蚕泽。

  • Activity退居后臺晌梨,且系統(tǒng)內(nèi)存不足, 系統(tǒng)會殺死這個后臺狀態(tài)的Activity(此時這個Activity引用仍然處在任務棧中须妻,只是這個時候引用指向的對象已經(jīng)為null)仔蝌,若再次回到這個Activity,則會走onCreate()–>onStart()—>onResume()(將重新走一次Activity的初始化生命周期)

  • 鎖屏:onPause()->onStop()

  • 解鎖:onStart()->onResume()

Activity生命周期流程圖

通過Acitivty的xml標簽來改變?nèi)蝿諚5哪J行為
  • singleTop : 棧頂復用模式。這種模式下荒吏,如果新Activity已經(jīng)位于任務棧的棧頂敛惊,那么此Activity不會被重新創(chuàng)建,所以它的啟動三回調(diào)就不會執(zhí)行绰更,同時Activity的onNewIntent()方法會被回調(diào)瞧挤。如果Activity已經(jīng)存在但是不在棧頂,那么作用與standard模式一樣儡湾。
  • singleTask: 棧內(nèi)復用模式特恬。創(chuàng)建這樣的Activity的時候,系統(tǒng)會先確認它所需任務棧已經(jīng)創(chuàng)建徐钠,否則先創(chuàng)建任務棧癌刽。然后放入Activity,如果棧中已經(jīng)有一個Activity實例尝丐,那么這個Activity就會被調(diào)到棧頂显拜。onNewIntent(),并且singleTask會清理在當前Activity上面的所有Activity(clear top)
  • singleInstance : 加強版的singleTask模式摊崭,這種模式的Activity只能單獨位于一個任務棧內(nèi)讼油,由于棧內(nèi)復用的特性,后續(xù)請求均不會創(chuàng)建新的Activity呢簸,除非這個獨特的任務棧被系統(tǒng)銷毀了矮台。

Activity的堆棧管理以ActivityRecord為單位,所有的ActivityRecord都放在一個List里面根时∈莺眨可以認為一個ActivityRecord就是一個Activity棧


Activity緩存方法

onSaveInstanceState()回調(diào)方法,一定會在Activity被回收之前調(diào)用蛤迎。方法中有一個Bundle參數(shù)确虱,putString()、putInt()等方法需要傳入兩個參數(shù)替裆,一個鍵一個值校辩。數(shù)據(jù)保存之后會在onCreate中恢復窘问,onCreate也有一個Bundle類型的參數(shù)。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //這里宜咒,當Acivity第一次被創(chuàng)建的時候為空
        //所以我們需要判斷一下
        if( savedInstanceState != null ){
            savedInstanceState.getString("anAnt");
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString("anAnt","Android");

    }

  • onSavaInstanceState() 方法被調(diào)用的幾種情況
    1.當按下HOME鍵時:
    因為系統(tǒng)不知道你按下HOME鍵后要運行多少其他的程序惠赫,自然也不知道Activity是否會被銷毀,故系統(tǒng)會調(diào)用onSaveInstanceState()故黑,讓用戶有機會保存某些非永久性的數(shù)據(jù)儿咱。
    2.按下多任務鍵,選擇運行其他程序時场晶。
    3.按下電源鍵鎖屏時混埠。
    4.從當前Activity中啟動一個新的Activity時。
    5.屏幕方向切換時:
    在屏幕切換之前系統(tǒng)會銷毀當前Activity诗轻,在屏幕切換之后系統(tǒng)又會自動地創(chuàng)建該Activity钳宪,所以該方法一定會被調(diào)用。

總而言之概耻,onSaveInstanceState()的調(diào)用遵循的原則是:當系統(tǒng)“未經(jīng)許可”銷毀了你的Activity時使套,就會被調(diào)用罐呼。因為系統(tǒng)必須提供一個讓你保存數(shù)據(jù)的機會鞠柄。

  • 注意:
    1.布局中的每一個View默認實現(xiàn)了onSaveInstanceState()方法,這樣的話嫉柴,這個UI的任何改變都會自動地存儲和在activity重新創(chuàng)建的時候自動地恢復厌杜。但是這種情況只有在你為這個UI提供了唯一的ID之后才起作用,如果沒有提供ID计螺,app將不會存儲它的狀態(tài)夯尽。
    2.由于onSaveInstanceState()方法調(diào)用的不確定性,你應該只使用這個方法去記錄activity的瞬間狀態(tài)(UI的狀態(tài))登馒。不應該用這個方法去存儲持久化數(shù)據(jù)匙握。當用戶離開這個activity的時候應該在onPause()方法中存儲持久化數(shù)據(jù)(例如應該被存儲到數(shù)據(jù)庫中的數(shù)據(jù))。
    3.onSaveInstanceState()如果被調(diào)用陈轿,這個方法會在onStop()前被觸發(fā)圈纺,但系統(tǒng)并不保證是否在onPause()之前或者之后觸發(fā)。

Fragment的生命周期以及與Activity之間的關(guān)系

注意和Activity相比的區(qū)別:

  • onAttach() onDetach()
  • onCreateView() onDestoryView()

Intent的使用方法麦射,可以傳遞哪些數(shù)據(jù)類型蛾娶?

通過查詢Intent/Bundle的API文檔,我們可以知道潜秋,Intent/Bundle支持傳遞基本類型的數(shù)據(jù)和基本類型的數(shù)組數(shù)據(jù)蛔琅,以及String/CharSequence類型的數(shù)據(jù)和String/CharSequence類型的數(shù)組數(shù)據(jù)。而對于其他類型的數(shù)據(jù)或數(shù)組數(shù)據(jù)則可以使對象序列化峻呛,例如實現(xiàn)Parcelable接口或?qū)崿F(xiàn)Serializable接口罗售。


為什么在Service中創(chuàng)建子線程而不是在Activity中辜窑?

這是因為Activity很難對Thread進行控制,當Activity被銷毀之后寨躁,就沒有任何其它的辦法可以再重新獲取到之前創(chuàng)建的子線程的實例谬擦。而且在一個Activity中創(chuàng)建的子線程,另一個Activity無法對其進行操作朽缎。但是Service就不同了惨远,所有的Activity都可以與Service進行關(guān)聯(lián),然后可以很方便地操作其中的方法话肖,即使Activity被銷毀了北秽,之后只要重新與Service建立關(guān)聯(lián),就又能夠獲取到原有的Service中Binder的實例最筒。因此贺氓,使用Service來處理后臺任務,Activity就可以放心地finish床蜘,完全不需要擔心無法對后臺任務進行控制的情況辙培。


Service的兩種啟動方法是?有什么區(qū)別邢锯?

1.在Context中通過public boolean bindService(Intent service, ServiceConnectionconn, int flags)方法來進行Service與Context的關(guān)聯(lián)并啟動扬蕊,并且Service的生命周期依附于Context(不求同年同月同日生,但求同年同月同日死)丹擎。
2.通過public ComponentName startService(Intent service)方法去啟動一個Service尾抑,此時Service的生命周期與啟動它的Context無關(guān)。
3.要注意的是無論如何蒂培,都需要在AndroidManifest.xml里注冊你的Service

<service
    android:name=".packnameName.youServiceName"
    android:enabled="true" />

廣播(Broadcast Receiver)的兩種動態(tài)注冊和靜態(tài)注冊有什么區(qū)別再愈?
  • 靜態(tài)注冊:在AndroidManifest.xml文件中進行注冊,當App退出后护戳,Receiver仍然可以接收到廣播并且進行相應的處理翎冲。
  • 動態(tài)注冊:在代碼中動態(tài)注冊,當App退出后媳荒,也就沒辦法在接受廣播了抗悍。

保證Service不被殺死的幾種方法

1.Service設置成START_STICKY

  • kill后會被重啟(等待5秒左右),重傳Intent肺樟,保持與重啟前一樣檐春。

2.提升Service的優(yōu)先級

  • 在AndroidManifest.xml文件中對于intent-file可以通過android:proiority = "1000"這個屬性設置最高優(yōu)先級,1000是最高值么伯,如果數(shù)字越小則優(yōu)先級越低疟暖,同樣適用于廣播
  • 【結(jié)論】目前看來,priority這個屬性貌似只適用于Broadcast俐巴,對于Service來說無效骨望。

3.onDestroy方法里重啟Service

  • Service + Broadcast 方式,就是當Service執(zhí)行onDestory()的時候欣舵,發(fā)送一個自定義的廣播擎鸠,當收到廣播的時候,重新啟動service缘圈。
  • 也可以直接在onDestroy()里startService
  • 【結(jié)論】當使用助手類軟件或者直接在設置里強制停止應用時劣光,App進程直接被結(jié)束,onDestroy方法都進不來糟把,還是無法徹底保證绢涡。

4.監(jiān)聽系統(tǒng)廣播判斷Service狀態(tài)

  • 通過系統(tǒng)的一些廣播,比如:手機重啟遣疯、界面喚醒雄可、應用狀態(tài)改變等等監(jiān)聽并捕獲到,然后判斷我們的Service是否還存活缠犀。
  • 【結(jié)論】這也能算是一種措施数苫,不過見聽多了會導致Service很混亂,不方便辨液。

5.root之后放到System/app變成系統(tǒng)級應用

6.放一個像素在前臺


如何判斷應用被強殺

在Application中定義一個Static常量虐急,賦值為-1,在Splash界面改為0室梅,如果被強殺戏仓,application重新初始化,在父類Activity判斷該常量的值亡鼠。

應用被強殺如何解決

如果在每一個Activity的onCreate里判斷是否被強殺,冗余了敷待,封裝到Activity的父類中间涵,如果被強殺,跳轉(zhuǎn)回主界面榜揖,如果沒有被強殺勾哩,執(zhí)行Activity的初始化操作,給主界面?zhèn)鬟fintent參數(shù)举哟,主界面會調(diào)用onNewIntent方法思劳,在onNewIntent跳轉(zhuǎn)到歡迎頁面,重新來一遍流程妨猩。

Asset目錄與res目錄的區(qū)別

res 目錄下面有很多文件潜叛,例如 drawable,mipmap,raw 等。res 下面除了 raw 文件不會被壓縮外,其余文件都會被壓縮威兜。同時 res目錄下的文件可以通過R 文件訪問销斟。Asset 也是用來存儲資源,但是 asset 文件內(nèi)容只能通過路徑或者 AssetManager 讀取椒舵。

Android怎么加速啟動Activity

啟動應用 :Application 的構(gòu)造方法蚂踊,onCreate 方法中不要進行耗時操作,數(shù)據(jù)預讀取(例如 init 數(shù)據(jù)) 放在異步中操作
啟動普通的Activity:A 啟動B 時不要在 A 的 onPause 中執(zhí)行耗時操作笔宿。因為 B 的 onResume 方法必須等待 A 的 onPause 執(zhí)行完成后才能運行

Android內(nèi)存優(yōu)化方法:ListView優(yōu)化犁钟,及時關(guān)閉資源,圖片緩存等等泼橘。

View和View Group的區(qū)別特纤?自定義View的過程?
  • Android的UI界面都是由View和ViewGroup及其派生類組合而成的侥加。其中捧存,View是所有UI組件的基類,而 ViewGroup是容納這些組件的容器担败,其本身也是從View派生出來的昔穴。View對象是Android平臺中用戶界面體現(xiàn)的基礎單位。View類是它稱為“widgets(工具)”的子類的基礎提前,它們提供了諸如文本輸入框和按鈕之類的UI對象的完整實現(xiàn)吗货。ViewGroup類同樣為其被稱為“Layouts(布局)”的子類奠定了基礎,它們提供了象流式布局狈网、表格布局以及相對布局之類的布局架構(gòu)宙搬。

  • 如何自定義控件:
    1.自定義屬性的聲明和獲取

    • 分析需要的自定義屬性
    • 在res/values/attrs.xml定義聲明
    • 在layout文件中進行使用
    • 在View的構(gòu)造方法中進行獲取

    2.測量onMeasure
    3.布局onLayout(ViewGroup)
    4.繪制onDraw
    5.onTouchEvent
    6.onInterceptTouchEvent(ViewGroup)
    7.狀態(tài)的恢復與保存


Content的區(qū)別
  • Activity和Service以及Application的Context是不一樣的,Activity繼承自ContextThemeWraper.其他的繼承自ContextWrapper
  • 每一個Activity和Service以及Application的Context都是一個新的ContextImpl對象
  • getApplication()用來獲取Application實例的,但是這個方法只有在Activity和Service中才能調(diào)用的到拓哺。那么也許在絕大多數(shù)情況下我們都是在Activity或者Service中使用Application的勇垛,但是如果在一些其它的場景,比如BroadcastReceiver中也想獲得Application的實例士鸥,這時就可以借助getApplicationContext()方法闲孤,getApplicationContext()比getApplication()方法的作用域會更廣一些,任何一個Context的實例烤礁,只要調(diào)用getApplicationContext()方法都可以拿到我們的Application對象讼积。
  • Activity在創(chuàng)建的時候會new一個ContextImpl對象并在attach方法中關(guān)聯(lián)它,Application和Service也差不多脚仔。ContextWrapper的方法內(nèi)部都是轉(zhuǎn)調(diào)ContextImpl的方法
  • 創(chuàng)建對話框傳入Application的Context是不可以的
  • 盡管Application勤众、Activity、Service都有自己的ContextImpl鲤脏,并且每個ContextImpl都有自己的mResources成員们颜,但是由于它們的mResources成員都來自于唯一的ResourcesManager實例吕朵,所以它們看似不同的mResources其實都指向的是同一塊內(nèi)存
  • Context的數(shù)量等于Activity的個數(shù) + Service的個數(shù) + 1,這個1為Application

IntentService的使用場景與特點

IntentService是Service的子類掌桩,是一個異步的边锁,會自動停止的服務,很好解決了傳統(tǒng)的Service中處理完耗時操作忘記停止并銷毀Service的問題
優(yōu)點:

  • 一方面不需要自己去new Thread
  • 另一方面不需要考慮在什么時候關(guān)閉該Service
    onStartCommand中回調(diào)了onStart波岛,onStart中通過mServiceHandler發(fā)送消息到該handler的handleMessage中去茅坛。最后handleMessage中回調(diào)onHandleIntent(intent)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(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
  • 正文 為了忘掉前任禽笑,我火速辦了婚禮,結(jié)果婚禮上蛉鹿,老公的妹妹穿的比我還像新娘滨砍。我一直安慰自己,他們只是感情好妖异,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著领追,像睡著了一般他膳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绒窑,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天棕孙,我揣著相機與錄音,去河邊找鬼。 笑死蟀俊,一個胖子當著我的面吹牛钦铺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肢预,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼矛洞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了烫映?” 一聲冷哼從身側(cè)響起沼本,我...
    開封第一講書人閱讀 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級特大地震影響,放射性物質(zhì)發(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)容