操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    為什么會(huì)有Activity?

    安卓應(yīng)用開(kāi)發(fā)的時(shí)候,首先接觸到的就是四大組件之一 Activity,可曾深入思考一下,為什么會(huì)有 Activity,安卓系統(tǒng)設(shè)計(jì)這個(gè)組件的目的是什么呢?

    1. Activity 是系統(tǒng)與用戶交互的載體,由于用戶的行為不可預(yù)期性,導(dǎo)致 Activity 的狀態(tài)比較復(fù)雜,管理起來(lái)也比較麻煩,衍生出一套解決方案
    2. 安卓系統(tǒng)中的很多應(yīng)用,沒(méi)有可見(jiàn)的界面,可以沒(méi)有 Activity。Activity 很重要,但并非不可缺少。

    Activity 的生命周期

    關(guān)鍵方法

    • onCreate
    • onStart
    • onResume
    • onPause
    • onStop
    • onDestory

    生命周期回調(diào)中的方法,不可以做耗時(shí)的操作,尤其是onResume和onPause,這兩個(gè)方法在 Activity 的狀態(tài)管理中,會(huì)頻繁的調(diào)用。

    典型場(chǎng)景下的生命周期回調(diào)

    A ---> B ---> A

    標(biāo)準(zhǔn)模式下,A 啟動(dòng) B, B 再返回 A 頁(yè)面

    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onResume
    D/LifeCycle: A1 onPause
    D/LifeCycle: A2 OnCreate
    D/LifeCycle: A2 onStart
    D/LifeCycle: A2 onResume
    D/LifeCycle: A1 onStop
    D/LifeCycle: A2 onPause
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onResume
    D/LifeCycle: A2 onDestroy
    

    A 頁(yè)面啟動(dòng)后,旋轉(zhuǎn)屏幕

    默認(rèn)配置下,旋轉(zhuǎn)屏幕

    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onResume
    D/LifeCycle: A1 onPause
    D/LifeCycle: A1 onStop
    D/LifeCycle: A1 onDestroy
    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onRestoreInstanceState
    D/LifeCycle: A1 onResume
    

    A 頁(yè)面中還有一些關(guān)鍵方法,同時(shí)也添加了日志,但是并沒(méi)有輸出

    • onConfigChange
    • onSaveInstanceState

    但這兩個(gè)方法并沒(méi)有被調(diào)用

    
        @Override
        protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
            Log.d("LifeCycle","A1 onRestoreInstanceState");
        }
    
        @Override
        public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
            super.onSaveInstanceState(outState, outPersistentState);
            Log.d("LifeCycle","A1 onSaveInstanceState");
        }
    
        @Override
        public void onConfigurationChanged(@NonNull Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            Log.d("LifeCycle","A1 onConfigureChange");
    
        }
        
    

    關(guān)于生命周期的兩個(gè)擴(kuò)展問(wèn)題

    1. 什么情況下,A 頁(yè)面會(huì)調(diào)用 onPause ,但不會(huì)調(diào)用 onStop 方法
    2. onCreate 方法中的 Bundle 和 onRestoreInstanceState 中 Bundle 一樣嗎?能重復(fù)獲取嗎?

    Activity 啟動(dòng)模式和任務(wù)棧管理

    • standard
    • singleTask
    • singleTop
    • singleInstance

    如果對(duì)這個(gè)不了解,可以先閱讀官方文檔 Tasks and back stack,官方的講解非常的清晰易懂,同時(shí)配有插圖輔助理解。

    以下內(nèi)容摘自官方文檔,配合簡(jiǎn)要說(shuō)明。

    standard

    Default. The system creates a new instance of the activity in the task from which it was started and routes the intent to it. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances.

    關(guān)鍵點(diǎn):默認(rèn)會(huì)初始化多次,每個(gè)任務(wù)棧可以有多個(gè)實(shí)例

    singleTop

    If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances (but only if the activity at the top of the back stack is not an existing instance of the activity).
    For example, suppose a task's back stack consists of root activity A with activities B, C, and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D. If D has the default "standard" launch mode, a new instance of the class is launched and the stack becomes A-B-C-D-D. However, if D's launch mode is "singleTop", the existing instance of D receives the intent through onNewIntent(), because it's at the top of the stack—the stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new instance of B is added to the stack, even if its launch mode is "singleTop".

    關(guān)鍵點(diǎn):棧頂?shù)娜绻羌磳⒁獑?dòng)的 Activity,會(huì)直接啟動(dòng)當(dāng)前 Activity,同時(shí)調(diào)用 onNewIntent() 方法,而不是 onCreate 方法

    singleTask

    The system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.

    關(guān)鍵點(diǎn):首次創(chuàng)建該 Activity時(shí),新建一個(gè) task;非首次,共用之前的,同時(shí)回調(diào) onNewIntent()方法

    同時(shí) singleTask 下,Activity 的生命周期回調(diào)也會(huì)有所不同

    A--->B--->A 日志如下

    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onResume
    D/LifeCycle: A1 onPause
    
    D/LifeCycle: A2 OnCreate
    D/LifeCycle: A2 onStart
    D/LifeCycle: A2 onResume
    D/LifeCycle: A1 onStop
    
    D/LifeCycle: A2 onPause
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onNewIntent
    D/LifeCycle: A1 onResume
    D/LifeCycle: A2 onDestroy
     
    

    再次啟動(dòng) A 的時(shí)候,B 直接回調(diào)了 onDestory 方法,返回棧被清空。

    singleInstance

    Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task; any activities started by this one open in a separate task.

    關(guān)鍵點(diǎn):獨(dú)占任務(wù)棧

    A-->B-->A -->返回-->返回
    生命周期的日志如下

    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onResume
    D/LifeCycle: A1 onPause
    
    D/LifeCycle: A2 OnCreate
    D/LifeCycle: A2 onStart
    D/LifeCycle: A2 onResume
    D/LifeCycle: A1 onStop
    
    D/LifeCycle: A2 onPause
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onNewIntent
    D/LifeCycle: A1 onResume
    
    D/LifeCycle: A1 onPause
    D/LifeCycle: A2 onStart
    D/LifeCycle: A2 onResume
    
    D/LifeCycle: A1 onStop
    D/LifeCycle: A1 onDestroy
    D/LifeCycle: A2 onPause
    D/LifeCycle: A2 onDestroy
    
    

    B 再次啟動(dòng) A 后,之前的任務(wù)棧被共用,A 在一個(gè)新的任務(wù)棧中。

    Intent FLAG

    • FLAG_ACTIVITY_NEW_TASK
    • FLAG_ACTIVITY_SINGLE_TOP
    • FLAG_ACTIVITY_CLEAR_TOP

    如果同時(shí)在 manifest 和 Intent FLAG 定義,最終會(huì)以 Intent FLAG 中定義的為準(zhǔn)。

    FLAG_ACTIVITY_NEW_TASK

    This produces the same behavior as the "singleTask" launchMode value

    關(guān)鍵點(diǎn):和 singleTask 效果一樣。

    FLAG_ACTIVITY_SINGLE_TOP

    This produces the same behavior as the "singleTop" launchMode value

    關(guān)鍵點(diǎn):和 singleTop 效果一樣。

    FLAG_ACTIVITY_CLEAR_TOP

    If the activity being started is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it are destroyed and this intent is delivered to the resumed instance of the activity (now on top), through onNewIntent()).

    FLAG_ACTIVITY_CLEAR_TOP is most often used in conjunction with FLAG_ACTIVITY_NEW_TASK. When used together, these flags are a way of locating an existing activity in another task and putting it in a position where it can respond to the intent.

    關(guān)鍵點(diǎn):如果已經(jīng)在當(dāng)前任務(wù)棧,會(huì)清空上面的頁(yè)面,把自己提升到棧頂,同時(shí)回調(diào) onNewIntent(),一般和FLAG_ACTIVITY_NEW_TASK共用,與singleTask 有點(diǎn)類似。

    TaskAffinity

    taskAffinity 是為了更好的管理 Activity 和任務(wù)棧的關(guān)系 。默認(rèn)情況下,同一個(gè) App 的所有的 Activity 都在一個(gè) task 中(標(biāo)準(zhǔn)模式)。但如果有多個(gè) task,當(dāng)啟動(dòng)一個(gè) Activity 時(shí),優(yōu)先選擇哪一個(gè) task 呢?可以通過(guò) taskAffinity 來(lái)定制。并且不同的 App,也可以共享同一個(gè) Affinity。一個(gè) App 中,也可以有多個(gè)不同的 taskAffinity。

    再?gòu)?fù)雜一些的任務(wù)棧管理方案,在項(xiàng)目中也很少會(huì)用到了。

    Activity 的數(shù)據(jù)恢復(fù)和狀態(tài)恢復(fù)

    什么情況下需要數(shù)據(jù)和狀態(tài)恢復(fù)呢?

    1. 異常退出,因內(nèi)存等原因,被系統(tǒng)回收,再次回到前臺(tái)時(shí),能夠恢復(fù)離開(kāi)時(shí)的狀態(tài)
    2. 異常中斷,比如看新聞時(shí),被一個(gè)電話打斷,接完電話再回來(lái)時(shí),希望繼續(xù)剛才閱讀的位置繼續(xù)。

    和狀態(tài)恢復(fù)相關(guān)的關(guān)鍵方法有兩個(gè)

    
        @Override
        public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
            super.onSaveInstanceState(outState, outPersistentState);
            Log.d("LifeCycle","A2 onSaveInstanceState");
        }
    
        @Override
        protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
            Log.d("LifeCycle","A2 onRestoreInstanceState");
        }
        
    

    實(shí)際驗(yàn)證下來(lái),這兩個(gè)方法的調(diào)用都不正常,在不同版本、不同手機(jī)上會(huì)有差異,可靠性無(wú)法保障。

    橫豎屏切換時(shí),Activity 生命周期的變化

    在這里,典型場(chǎng)景下 Activity 生命周期變化 中,已經(jīng)說(shuō)明了默認(rèn)情況下(不設(shè)置 Activity 的 android:configChanges 屬性),旋轉(zhuǎn)屏幕Activity 生命周期的變化。還有另外一個(gè)場(chǎng)景,做一些系統(tǒng)配置后,生命周期的回調(diào)會(huì)發(fā)生改變。

    再看一下 設(shè)置 android:configChanges="orientation" 屬性后,生命周期的變化

    A 啟動(dòng)-->旋轉(zhuǎn)-->旋轉(zhuǎn)-->退出

    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onResume
    
    D/LifeCycle: A1 onPause
    D/LifeCycle: A1 onStop
    D/LifeCycle: A1 onDestroy
    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onRestoreInstanceState
    D/LifeCycle: A1 onResume
    
    D/LifeCycle: A1 onPause
    D/LifeCycle: A1 onStop
    D/LifeCycle: A1 onDestroy
    D/LifeCycle: A1 oncreate
    D/LifeCycle: A1 onStart
    D/LifeCycle: A1 onRestoreInstanceState
    D/LifeCycle: A1 onResume
    
    D/LifeCycle: A1 onPause
    D/LifeCycle: A1 onStop
    D/LifeCycle: A1 onDestroy
    

    屬性配置為 android:configChanges="orientation|screenSize" 后,生命周期的變化

    A 啟動(dòng)-->旋轉(zhuǎn)-->旋轉(zhuǎn)-->退出

    D/LifeCycle: A2 OnCreate
    D/LifeCycle: A2 onStart
    D/LifeCycle: A2 onResume
    
    D/LifeCycle: A2 onConfigureChange
    
    D/LifeCycle: A2 onConfigureChange
    
    D/LifeCycle: A2 onPause
    D/LifeCycle: A2 onDestroy
    
    

    所以,在使用的時(shí)候,需要把 screenSize 和 orientation 配合使用。

    Activity 的擴(kuò)展問(wèn)題 - TODO

    Activity 這個(gè)主題下,遺留的 7 個(gè)擴(kuò)展問(wèn)題,這些問(wèn)題的解答,會(huì)在
    Android 高級(jí) 完成后再來(lái)解決,每個(gè)擴(kuò)展問(wèn)題,都可以單獨(dú)一個(gè)章節(jié)闡述,也是我們?cè)陧?xiàng)目開(kāi)發(fā)中,知道深入思考的問(wèn)題。

    • 影響 Activity 啟動(dòng)速度的因素有哪些?如何優(yōu)化 Activity 的啟動(dòng)速度?
    • 微信、支付寶支付界面的啟動(dòng)方案如何設(shè)計(jì),有哪些借鑒意義?
    • Activity 的數(shù)據(jù)恢復(fù)的其他方案有哪些(至少 3 種),這些方案各有哪些優(yōu)劣?
    • LifeCycle 如何觀察 Activity 的聲明周期?使用了何種設(shè)計(jì)模式,闡述下核心的設(shè)計(jì)流程
    • 四種啟動(dòng)模式,各自典型的應(yīng)用場(chǎng)景有哪些,如果自己設(shè)計(jì)管理 Activity 的任務(wù)棧,有哪些思路可以參考?
    • 從 Activity 關(guān)鍵生命周期方法中,如何統(tǒng)計(jì)一個(gè) Activity 的用戶使用時(shí)長(zhǎng),在做的時(shí)候,應(yīng)該注意哪些問(wèn)題?
    • Activity 、Window和 View 之間的關(guān)系

    Rust錯(cuò)誤處理概述

    Rust的可靠性也體現(xiàn)在錯(cuò)誤處理上:大部分情況下,在編譯時(shí)提示錯(cuò)誤,使得程序員在coding階段進(jìn)行處理。 錯(cuò)誤分類:

    • 可恢復(fù)錯(cuò)誤,如文件未找到,可再次嘗試
    • 不可恢復(fù)錯(cuò)誤,即bug。如訪問(wèn)的索引超出范圍

    Rust中沒(méi)有類似其他語(yǔ)言中的異常機(jī)制,針對(duì)可恢復(fù)錯(cuò)誤,使用Result<T, E>來(lái)處理。不可恢復(fù)的錯(cuò)誤用panic!宏處理。

    不可恢復(fù)的錯(cuò)誤與panic!宏

    當(dāng)panic!宏執(zhí)行時(shí):

    • 程序會(huì)打印一個(gè)錯(cuò)誤信息
    • 展開(kāi)(unwind)并清理調(diào)用棧(Stack)
    • 退出程序

    展開(kāi)或終止調(diào)用棧

    默認(rèn)情況下,當(dāng)panic發(fā)生,程序會(huì)展開(kāi)調(diào)用棧(工作量大):

    • Rust沿著調(diào)用棧往回走
    • 清理每個(gè)遇到的函數(shù)中的數(shù)據(jù)

    還可以立即終止調(diào)用棧:

    • 不進(jìn)行清理,直接終止程序
    • 內(nèi)存需要操作系統(tǒng)自己清理

    當(dāng)我們將設(shè)置從展開(kāi)改為中止時(shí),二進(jìn)制文件會(huì)更小:在Cargo.toml中適當(dāng)?shù)膒rofile部分進(jìn)行設(shè)置。例:

    [package]
    name="my-project"
    version="0.1.0"
    edition="2021"
    
    # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    
    #release模式下生效
    [profile.release]
    panic='abort'
    //src/main.rs
    fn main() {
        panic!("crash and burn!");//主動(dòng)調(diào)用panic!宏
    }

    嘗試運(yùn)行

    > cargo run
       Compiling my-project v0.1.0 (E:\Projects\Rust\my-project)
        Finished dev [unoptimized + debuginfo] target(s) in 0.28s
         Running `target\debug\my-project.exe`
    thread 'main' panicked at 'crash and burn!', src\main.rs:3:5
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    error: process didn't exit successfully: `target\debug\my-project.exe` (exit code: 101

    可以看到程序是在src\main.rs:3:5出panic,另一個(gè)例子:

    //src/main.rs
    fn main() {
        let v=vec![1, 2, 3];
        v[666];
    }

    運(yùn)行報(bào)錯(cuò):

    > cargo run
        Finished dev [unoptimized + debuginfo] target(s) in 0.00s
         Running `target\debug\my-project.exe`
    thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 666', src\main.rs:4:5
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    error: process didn't exit successfully: `target\debug\my-project.exe` (exit code: 101)

    可以看到,這里我們沒(méi)有主動(dòng)調(diào)用panic!宏,那么它是誰(shuí)調(diào)用的呢?是在我們調(diào)用的其它代碼里調(diào)用的。這里就是索引訪問(wèn)Vector的地方調(diào)用的。但是這里的錯(cuò)誤指向是src\main.rs:4:5。如果我們想獲得更詳細(xì)的信息應(yīng)該怎么做? 應(yīng)該設(shè)置環(huán)境變量RUST_BACKTRACE=1來(lái)展示錯(cuò)誤的回溯信息:

    > set RUST_BACKTRACE=1 && cargo run
        Finished dev [unoptimized + debuginfo] target(s) in 0.01s
         Running `target\debug\my-project.exe`
    thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 666', src\main.rs:4:5
    stack backtrace:
       0: std::panicking::begin_panic_handler
                 at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c\/library\std\src\panicking.rs:517
       1: core::panicking::panic_fmt
                 at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c\/library\core\src\panicking.rs:100
       2: core::panicking::panic_bounds_check
                 at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c\/library\core\src\panicking.rs:76
       3: core::slice::index::impl$2::index<i32>
                 at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c\library\core\src\slice\index.rs:184
       4: core::slice::index::impl$0::index<i32,usize>
                 at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c\library\core\src\slice\index.rs:15
       5: alloc::vec::impl$16::index<i32,usize,alloc::alloc::Global>
                 at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c\library\alloc\src\vec\mod.rs:2496
       6: my_project::main
                 at .\src\main.rs:4
       7: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
                 at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c\library\core\src\ops\function.rs:227
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    error: process didn't exit successfully: `target\debug\my-project.exe` (exit code:
    101)

    注意:set RUST_BACKTRACE=1 && cargo run在Windows powershell下不生效(不知為啥),建議在cmd下使用。

    使用panic!宏產(chǎn)生的回溯信息

    panic!可能出現(xiàn)在:

    • 我們寫(xiě)的代碼中
    • 我們依賴的代碼中

    可以通過(guò)調(diào)用panic!的函數(shù)的回溯信息來(lái)定位引起問(wèn)題的代碼,通過(guò)設(shè)置環(huán)境變量RUST_BACKTRACE=1來(lái)獲取回溯信息。但是當(dāng)這個(gè)環(huán)境變量為1時(shí),可能有某些細(xì)節(jié)被省略了,可以設(shè)置RUST_BACKTRACE=full來(lái)獲取完整的信息。 注:為了獲取帶有調(diào)試信息的回溯,必須啟用調(diào)試符號(hào),即cargo build或run時(shí)不帶--release。

網(wǎng)站首頁(yè)   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有