Android面試一天一題(4 Day)

我一般面試技術(shù)分兩方面了解面試者,一是測重問面試者細(xì)節(jié)的地方,看對方是否真如簡歷上所說對XX“精通”、“熟悉”、“有一定的見解”,有實(shí)踐經(jīng)驗(yàn)的積累。別一種是側(cè)重考察對方對問題(可以是未知問題)的理解和解決問題的思路。

面試題: 如何判斷Activity是否在運(yùn)行?

如下這場景我相信很多人都遇到過,這段話也是從某個帖子截取出來的:

從Activity A 啟動一個線程去進(jìn)行網(wǎng)絡(luò)上傳操作,在A中設(shè)立一個回調(diào)函數(shù),當(dāng)上傳操作完成以后,在A的這個回調(diào)函數(shù)中會彈出一個對話框,用來顯示回調(diào)信息??墒钱?dāng)上傳的過程還在進(jìn)行的時候,我按下back鍵,A的activity 被銷毀了,可是那個上傳的線程還在進(jìn)行,當(dāng)那個線程結(jié)束后,本來應(yīng)該在A中彈出一個對話框,可是由于A已經(jīng)不存在了,系統(tǒng)就會報錯提示,“將對話框顯示在不存在的頁面上”,然后程序就掛掉了。

我看到過很多人用Handler來充當(dāng)上面所提到的“回調(diào)函數(shù)”,即工作線程完成工作后,通過主線程的Handler處理UI更新,如彈出提示Dialog。可能有些人沒有弄明白,Activity都被系統(tǒng)銷毀了,工作線程怎么還能調(diào)它的變量呢?其實(shí)所謂的Activity銷毀只是不再受系統(tǒng)的AMS控制,但Activity這個對象的實(shí)例還是存在于內(nèi)存中的,具體什么時候真正把這個對象實(shí)例也銷毀(回收)了,就要看內(nèi)存回收機(jī)制了,哪怕是這個實(shí)例沒有可達(dá)的引用了也不一定會馬上回收。

針對這種用Handler更新UI的情況,我們需要在操作UI前判斷一下此Activity是否已被銷毀。很多人可能都用過isFinishing來判斷,用多了就會發(fā)現(xiàn)好象不太準(zhǔn),為什么呢,看一下它的源代碼:

    /**
     * Check to see whether this activity is in the process of finishing,
     * either because you called {@link #finish} on it or someone else
     * has requested that it finished.  This is often used in
     * {@link #onPause} to determine whether the activity is simply pausing or
     * completely finishing.
     *
     * @return If the activity is finishing, returns true; else returns false.
     *
     * @see #finish
     */
    public boolean isFinishing() {
        return mFinished;
    }

    /**
     * Returns true if the final {@link #onDestroy()} call has been made
     * on the Activity, so this instance is now dead.
     */
    public boolean isDestroyed() {
        return mDestroyed;
    }

而mFinished是在finish()中被賦值的,也就是說只有通過調(diào)用finish()結(jié)束的Activity,mFinished的值才會被置為true。所以有時候Activity的生命周期沒有按我們預(yù)想的來走時(如內(nèi)存緊張時),會出現(xiàn)判斷出錯的情況。

Android源碼可以使用這個網(wǎng)站查詢:androidxref

看看Google工程師是怎么判斷的(來源于Android源碼中的Call應(yīng)用,AsyncTask中的onPostExecute片段):

    @Override
    protected void onPostExecute(Void result) {
        final Activity activity = progressDialog.getOwnerActivity();

        if (activity == null || activity.isDestroyed() || activity.isFinishing()) {
            return;
        }

        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

多了一個isDestroyed()的判斷。

小結(jié)

如果對方?jīng)]聽說過isFinishing函數(shù),那可以讓他從自己的角度看如何解決這個問題,正好可以看看他的邏輯思維是否清晰合理。工作中往往會遇到,一些求職者由于之前是做其他方面剛轉(zhuǎn)Android開發(fā),對Android的了解還不夠,但有很強(qiáng)理解和學(xué)習(xí)能力,通過引導(dǎo)發(fā)現(xiàn)他可以快速的得到合理的解決方案的話,我一般都很樂意要這樣的人。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容