Fragment 懶加載 與 getActivity()返回null的問題

最近實(shí)現(xiàn)了一個界面功能蚜锨,其實(shí)很簡單就是一個Tab,下面三個可滑動的view氏堤。使用TabLayout+ViewPager可以實(shí)現(xiàn)這樣的效果沙绝。一開始ViewPager中我放入的是一個view,但是功能實(shí)現(xiàn)完了之后鼠锈,感覺界面滑動不太順暢闪檬,生命周期什么的都不好控制,后來直接索性就換了Fragment 加載布局购笆。但是ViewPager有預(yù)加載機(jī)制粗悯,即是設(shè)置了預(yù)加載頁數(shù)為0,這個方法是不失效的同欠。因?yàn)樵谠摲椒ㄖ凶隽伺袛嘌辽贂虞d一頁。那么在這個activity剛創(chuàng)建的時候就變成需要初始化大量資源铺遂。所以采用懶加載的方式來處理衫哥。

重點(diǎn)Fragment里的setUserVisibleHint這個方法

官方api 介紹

Set a hint to the system about whether this fragment's UI is currently visible to the user. This hint defaults to true and is persistent across fragment instance state save and restore.
An app may set this to false to indicate that the fragment's UI is scrolled out of visibility or is otherwise not directly visible to the user. This may be used by the system to prioritize operations such as fragment lifecycle updates or loader ordering behavior.
Parameters

大概意思是這樣的:有道~~~

設(shè)置一個系統(tǒng)提示是否這個片段的UI是目前用戶可見的。這提示默認(rèn)為正確并持續(xù)在片段實(shí)例保存和恢復(fù)狀態(tài)襟锐。
應(yīng)用程序可以設(shè)置為false,以表明片段的UI是滾動的可見性或另有用戶不能直接看到撤逢。這可能是使用的系統(tǒng)優(yōu)化操作,比如片段的生命周期更新或加載程序命令的行為。
參數(shù)
isVisibleToUser真實(shí)如果這個片段的UI目前可見的用戶(默認(rèn)),如果它不是空的。

代碼 Fragment V4包下的
public class abstract  BaseFragment extends Fragment {
    /*
    * 當(dāng)前界面是否呈現(xiàn)給用戶的狀態(tài)標(biāo)志
    */
    protected boolean isVisible;
    /**
     * 重寫Fragment父類生命周期方法蚊荣,在onCreate之前調(diào)用該方法初狰,實(shí)現(xiàn)Fragment數(shù)據(jù)的緩加載.
     * @param isVisibleToUser 當(dāng)前是否已將界面顯示給用戶的狀態(tài)
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }
    /**
     * 當(dāng)界面呈現(xiàn)給用戶,即設(shè)置可見時執(zhí)行妇押,進(jìn)行加載數(shù)據(jù)的方法
     * 在用戶可見時加載數(shù)據(jù)跷究,而不在用戶不可見的時候加載數(shù)據(jù),是為了防止控件對象出現(xiàn)空指針異常
     */
    protected void onVisible(){
        setlazyLoad();
    }
    /**
     * 當(dāng)界面還沒呈現(xiàn)給用戶敲霍,即設(shè)置不可見時執(zhí)行
     */
    protected void onInvisible(){
    }
    /**
     * 加載數(shù)據(jù)方法俊马,必須由子類實(shí)現(xiàn)。
     */
    protected abstract  void setlazyLoad()肩杈;
}
子類實(shí)現(xiàn)
public class OpenResultFragment extends BaseFragment {
    // 標(biāo)志位柴我,標(biāo)志已經(jīng)初始化完成。
    private boolean isPrepared;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(LOG_TAG, "onCreateView");
        View view = inflater.inflate(R.layout.fragment_open_result, container, false);
        
        .........XXX初始化view的各控件

        isPrepared = true;    // 對標(biāo)識符進(jìn)行賦值動作
        lazyLoad();
        return view;
    }
    @Override
    protected void lazyLoad() {
        if(!isPrepared || !isVisible) {
            return;
        }
        //填充各控件的數(shù)據(jù)扩然,請求網(wǎng)絡(luò)數(shù)據(jù) 
    }
}

子類中增加了一個標(biāo)志位isPrepared艘儒,用于標(biāo)志是否初始化完成。然后在我們所需要的初始化操作完成之后調(diào)用夫偶,如上面的例子當(dāng)中界睁,在初始化view之后,設(shè)置 isPrepared為true兵拢,同時調(diào)用lazyLoad()方法翻斟。而在lazyLoad()當(dāng)中,判斷isPrepared和isVisible只要有一個不為true就不往下執(zhí)行说铃。也就是僅當(dāng)初始化完成访惜,并且可見的時候才繼續(xù)加載,這樣的避免了未初始化完成就使用而帶來的問題腻扇。

Fragment中調(diào)用getActivity為null的問題

今天在測試的時候债热,也發(fā)現(xiàn)了一個問題,F(xiàn)ragment基于Activity上幼苛,快速切換界面窒篱,或者什么情況下,會導(dǎo)致Activity銷毀舶沿,這種情況下舌剂,在Fragment中g(shù)etActivity獲取上下文,這樣后果就是應(yīng)用程序直接崩掉了暑椰,并且報空指針霍转。因?yàn)椋珹ctivity不存在了一汽,獲取一個不存在的東西避消,肯定是報error的低滩。
度娘了一把~~~~

解決方式1

查閱一下Fragment的生命周期:

在onAttach() 與 onDetach()方法之間 getActivity方法是存在,反之為null岩喷,因此恕沫,如果我正在做某些操作聯(lián)網(wǎng),在等待過程中點(diǎn)擊Back鍵返回纱意,使得這個Fragment被銷毀了婶溯,這時Fragment就會和Activity解除附著(onDetach),當(dāng)再試圖彈出Toast的時候偷霉,再次通過getActivity方法獲取上下文迄委,就報null了。

解決方式2

創(chuàng)建變量类少,保存實(shí)例叙身。
在Fragment附著在Activity上時用一個變量保存引用,即:

@Override
public void onAttach(Activity activity){
    this.mContext = activity;
}
解決方式3

獲取全局上下文硫狞,因?yàn)槿稚舷挛牡氖呛蛻?yīng)用程序的生命周期一致的信轿,不必?fù)?dān)心為null
Android程序中Application、Service和Activity都實(shí)現(xiàn)了Context残吩,但只有Application才能保證在程序運(yùn)行期間一直存在并且具有唯一性财忽,因此在程序中可以使用Application來獲得Context而不用擔(dān)心空指針。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泣侮,一起剝皮案震驚了整個濱河市即彪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旁瘫,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琼蚯,死亡現(xiàn)場離奇詭異酬凳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)遭庶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門宁仔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人峦睡,你說我怎么就攤上這事翎苫。” “怎么了榨了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵煎谍,是天一觀的道長。 經(jīng)常有香客問我龙屉,道長呐粘,這世上最難降的妖魔是什么满俗? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮作岖,結(jié)果婚禮上唆垃,老公的妹妹穿的比我還像新娘。我一直安慰自己痘儡,他們只是感情好辕万,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著沉删,像睡著了一般渐尿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丑念,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天涡戳,我揣著相機(jī)與錄音,去河邊找鬼脯倚。 笑死渔彰,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的推正。 我是一名探鬼主播恍涂,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼植榕!你這毒婦竟也來了再沧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤尊残,失蹤者是張志新(化名)和其女友劉穎炒瘸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寝衫,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顷扩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了慰毅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隘截。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖汹胃,靈堂內(nèi)的尸體忽然破棺而出婶芭,到底是詐尸還是另有隱情,我是刑警寧澤着饥,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布犀农,位于F島的核電站,受9級特大地震影響宰掉,放射性物質(zhì)發(fā)生泄漏井赌。R本人自食惡果不足惜谤逼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仇穗。 院中可真熱鬧流部,春花似錦、人聲如沸纹坐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耘子。三九已至果漾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谷誓,已是汗流浹背绒障。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捍歪,地道東北人户辱。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像糙臼,于是被迫代替她去往敵國和親庐镐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評論 25 707
  • Android Studio JNI流程首先在java代碼聲明本地方法 用到native關(guān)鍵字 本地方法不用去實(shí)現(xiàn)...
    MigrationUK閱讀 11,859評論 7 123
  • 片段 Fragment表示 Activity中的行為或用戶界面部分变逃。您可以將多個片段組合在一個 Activity ...
    岳小川閱讀 804評論 0 3
  • 雅思作文學(xué)習(xí)20160507 一必逆、介紹 Task 1 作文 20分鐘 分值占三分之一 字?jǐn)?shù)at least 150...
    小醇仔閱讀 608評論 0 0
  • 從定制公交上下來,前面是一個裊娜的背影揽乱。深栗色的頭發(fā)低低地扎成一束名眉,發(fā)尾有些小卷,自然地灑在背上凰棉。背挺得筆直的损拢,一...
    離曉曉閱讀 581評論 4 2