Android爬坑之旅之不易發(fā)現(xiàn)的BUG

在Android的app開(kāi)發(fā)過(guò)程中,除了機(jī)型適配等問(wèn)題,常常還會(huì)出一些特殊的bug景醇,這些bug往往需要特殊的場(chǎng)景情況下才會(huì)發(fā)生,這里羅列了一些平時(shí)項(xiàng)目中遇到的問(wèn)題及注意點(diǎn)吝岭。


App打包apk安裝后重復(fù)啟動(dòng)根界面的問(wèn)題

這個(gè)問(wèn)題很特殊三痰,一般情況下很難被發(fā)現(xiàn),是Android系統(tǒng)一直以來(lái)的一個(gè)Bug窜管。

當(dāng)我們把a(bǔ)pp打包成apk安裝程序散劫,通過(guò)點(diǎn)擊apk文件進(jìn)行安裝時(shí),會(huì)啟動(dòng)安裝界面幕帆,
并在安裝成功后會(huì)跳轉(zhuǎn)安裝完成界面获搏,
如圖:

安裝完成界面

我們點(diǎn)擊圖中的 打開(kāi)按鈕,此時(shí)會(huì)啟動(dòng)我們的app

這里為了讓大家更容易理解一些失乾,

我們假設(shè)app有兩個(gè)界面

  • 啟動(dòng)界面SplashActivity
  • 主界面MainActivity
  • app啟動(dòng)后打開(kāi)SplashActivity常熙,3秒后自動(dòng)跳轉(zhuǎn)MainActivity,界面不做強(qiáng)制finish

接下來(lái),我們需要了解下Task任務(wù)棧和Back Stack返回棧碱茁,
如果有同學(xué)對(duì)這兩個(gè)概念還不熟悉的裸卫,
可以看一下官方文檔,講得很詳細(xì):

Android任務(wù)和返回棧官方文檔

這里我們引用官方文檔的一句話(huà):

The device Home screen is the starting place for most tasks. When the user touches an icon in the application launcher (or a shortcut on the Home screen), that application's task comes to the foreground. If no task exists for the application (the application has not been used recently), then a new task is created and the "main" activity for that application opens as the root activity in the stack.

當(dāng)我們點(diǎn)擊home界面的應(yīng)用啟動(dòng)圖標(biāo)時(shí)(安裝完成界面點(diǎn)擊打開(kāi)同理)

如果沒(méi)有對(duì)應(yīng)Task任務(wù)棧存在纽竣,則會(huì)創(chuàng)建一個(gè)新的任務(wù)棧墓贿,
并且把應(yīng)用啟動(dòng)的首頁(yè)面作為根Activity放到任務(wù)棧中。

如果存在對(duì)應(yīng)的Task任務(wù)棧蜓氨,則會(huì)直接調(diào)用對(duì)應(yīng)的Task任務(wù)棧到前臺(tái)募壕,并將棧頂?shù)慕缑骘@示給用戶(hù),

那么當(dāng)我們的app啟動(dòng)后打開(kāi)SplashActivity并跳轉(zhuǎn)主界面MainActivity后,我們app的任務(wù)棧應(yīng)該如圖所示:

Paste_Image.png

此時(shí)语盈,當(dāng)我們點(diǎn)擊Home鍵退回到桌面,
app的Task任務(wù)棧進(jìn)入后臺(tái)缰泡,然后我們點(diǎn)擊桌面上的啟動(dòng)圖標(biāo)刀荒,

正常情況下,app應(yīng)該會(huì)把它對(duì)應(yīng)的Task任務(wù)棧調(diào)到前臺(tái)棘钞,并顯示剛剛棧頂?shù)腗ainActivity界面缠借,

正常流程

正常流程

然而,實(shí)際情況是宜猜,app會(huì)把它的Task任務(wù)棧調(diào)用到前臺(tái)泼返,

并在任務(wù)棧上重新創(chuàng)建新的SplashActivity ,再跳轉(zhuǎn)到MainActivity姨拥,

在不重新加載application的情況下绅喉,它又重新走了一遍啟動(dòng)的流程渠鸽,這個(gè)時(shí)候,我們會(huì)發(fā)現(xiàn)任務(wù)棧中的Activity重復(fù)了柴罐,SplashActivity跟MainActivity都變成了兩個(gè)

為了更清晰的讓大家理解徽缚,這里畫(huà)了兩個(gè)圖,

  • 錯(cuò)誤的bug流程
  • 錯(cuò)誤狀態(tài)下的Task任務(wù)棧

bug流程

Paste_Image.png

新調(diào)用的SplashActivity會(huì)被置于該app的task棧頂

Paste_Image.png

多出了兩個(gè)Activity

當(dāng)然這個(gè)bug一般用戶(hù)也很難注意到革屠,它的產(chǎn)生必須滿(mǎn)足下面的條件:

  • 點(diǎn)擊apk文件安裝app
  • 安裝完成界面點(diǎn)擊打開(kāi)按鈕
  • 點(diǎn)擊Home鍵凿试,進(jìn)入系統(tǒng)桌面,此時(shí)app退到后臺(tái)
  • 再點(diǎn)擊桌面上啟動(dòng)圖標(biāo)

那么對(duì)于這種問(wèn)題我們?nèi)绾蝸?lái)處理呢?

按照上文的舉例似芝,
在正常流程下啟動(dòng)app進(jìn)入MainActivity界面時(shí)的任務(wù)棧
:

正常情況

bug情況下那婉,會(huì)調(diào)起任務(wù)棧到前臺(tái)并添加根Acitivy SplashActivity到棧頂,此時(shí)的任務(wù)棧:

Paste_Image.png

我們可以看到党瓮,在bug情況下啟動(dòng)app時(shí)详炬,SplashActivity(app的根Activity)再次創(chuàng)建并疊加到Task任務(wù)棧上了

理應(yīng)只會(huì)出現(xiàn)在棧底的SplashActivity出現(xiàn)在了其他位置,所以這里我們直接判斷了app根Activity SplashActivity的位置

在app的SplashActivity(app的根Activity)的onCreate方法中通過(guò) isTaskRoot() 方法來(lái)判斷是否是任務(wù)棧中的根Activity麻诀,如果是就不做任何處理痕寓,如果不是則直接finish掉;

public class SplashActivity extends BaseActivity {
@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        setTheme(R.style.AppTheme_NoActionBar);
        super.onCreate(savedInstanceState);

        if (!isTaskRoot()) {
            finish();
            return;
        }
    }

}

這樣棧頂?shù)腟plashActivity在還未執(zhí)行其他代碼的情況下就finish()掉了,此時(shí)會(huì)顯示棧頂?shù)腗ainActivity蝇闭。


Android包含F(xiàn)ragment界面的Activity界面呻率,在app被系統(tǒng)釋放后,重新回到前臺(tái)時(shí)呻引,重建Activity造成Fragment重疊

隨著功能需求的多樣化礼仗,F(xiàn)ragment的應(yīng)用場(chǎng)景也是越來(lái)越廣,其中我們的首頁(yè)底欄可能是最常見(jiàn)的場(chǎng)景了逻悠。

那我們這里說(shuō)的app在被系統(tǒng)釋放后,重回前臺(tái)Activity時(shí)元践,重建造成Fragment重疊又是怎么回事呢?

我們知道童谒,要使用Fragment的Activity必須繼承v7的AppCompatActivity单旁,
而AppCompatActivity繼承自FragmentActivity

當(dāng)我們的app退到后臺(tái)處于容易被系統(tǒng)回收的狀態(tài)時(shí),會(huì)觸發(fā)我們的onSaveInstanceState方法饥伊,

而使用Fragment的Activity會(huì)調(diào)用到父類(lèi)FragmentActivity的onSaveInstanceState方法,

這里我截取FragmentActivity中onSaveInstanceState的關(guān)鍵代碼:

/**
     * Save all appropriate fragment state.
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Parcelable p = mFragments.saveAllState();//獲取FragmentManager保存的所有Fragments
        if (p != null) {
            outState.putParcelable(FRAGMENTS_TAG, p);//Fragment不為空象浑,執(zhí)行保存操作
        }
       ...
        }
    }

我們看到,這里的代碼把Fragment的狀態(tài)保存了下來(lái)琅豆,
而在FragmentActivity的onCreate方法中愉豺,又將這些Fragment重建了:

 /**
     * Perform initialization of all fragments and loaders.
     */
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mFragments.attachHost(null /*parent*/);

        super.onCreate(savedInstanceState);

        ...
        if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            mFragments.restoreAllState(p, nc != null ? nc.fragments : null);

        ...   
        }

   ...
    }

也就是說(shuō),界面因?yàn)楸幌到y(tǒng)釋放后重建茫因,重新觸發(fā)了Activity的onCreate方法蚪拦,

如果開(kāi)發(fā)人員沒(méi)有判斷onCreate的saveInstance變量調(diào)整創(chuàng)建邏輯,直接執(zhí)行了Fragment的創(chuàng)建代碼,那新建的Fragment就會(huì)跟系統(tǒng)恢復(fù)的重疊驰贷。

這個(gè)問(wèn)題一方面因?yàn)閮?nèi)存不足的極端情況下才會(huì)觸發(fā)(紅米等低端設(shè)備屬于常態(tài)盛嘿,經(jīng)常會(huì)釋放app),

另一方面由于部分開(kāi)發(fā)的Fragment界面不是透明的饱苟,因此即使疊加了也不一定能發(fā)現(xiàn)這個(gè)問(wèn)題孩擂。

那對(duì)于這樣的問(wèn)題,我們?nèi)绾翁幚砟叵浒荆@里給出了三種處理方案:

1.在Activity的onCreate中判斷savedInstanceState變量是否為null类垦,
如果savedInstanceState為null說(shuō)明是界面是新建,則執(zhí)行完整的fragment tab初始化工作城须;
如果savedInstanceState不為null蚤认,說(shuō)明Activity是被釋放重建,那就不執(zhí)行Fragment的創(chuàng)建糕伐,執(zhí)行相關(guān)邏輯代碼砰琢,

代碼如下:

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState == null) {
        //界面正常情況下create時(shí)的邏輯
            initTab();
        }
        else {
        //界面在內(nèi)存不足情況下被強(qiáng)制回收后重新create的邏輯
        }
}

2.這個(gè)方法我稱(chēng)之為懶人做法

使用了Fragment的Activity在調(diào)用onCreate方法時(shí)會(huì)首先調(diào)用super.onCreate()

而super.onCreate最終又會(huì)執(zhí)行FragmentActivity的onCreate方法,

從上文截取的代碼中良瞧,我們看到陪汽,F(xiàn)ragmentActivity的onCreate方法會(huì)判斷saveInstanceState里的Fragment是否為空,不為空就恢復(fù)保存的Fragment

if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            mFragments.restoreAllState(p, nc != null ? nc.fragments : null);

        ...   
        }

也就是說(shuō)褥蚯,我們?cè)趫?zhí)行到這段代碼前把FRAGMENTS_TAG對(duì)應(yīng)的值清空挚冤,那樣就不會(huì)觸發(fā)系統(tǒng)重建的恢復(fù)了

那么我們只需要在使用Fragment的Activity的onCreate方法添加以下代碼就可以了:

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            savedInstanceState.putParcelable("android:support:fragments", null);//清空保存Fragment的狀態(tài)數(shù)據(jù)
        }
        super.onCreate(savedInstanceState);
}

這樣,在執(zhí)行到FragmentActivity的onCreate前赞庶,F(xiàn)RAGMENTS_TAG對(duì)應(yīng)的數(shù)據(jù)就已經(jīng)清空了训挡。

3.同樣是懶人方法,直接重寫(xiě)onSaveInstanceState方法歧强,注釋掉super.onSaveInstanceState澜薄,這樣就不會(huì)保存Fragment的數(shù)據(jù)了,不過(guò)副作用也是非常明顯摊册,就是onSaveInstanceState就完全失去作用了肤京,
所以并不太推薦大家這么去做,僅做參考:

  @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
//        super.onSaveInstanceState(outState, outPersistentState);
    }

關(guān)于模擬app被釋放的場(chǎng)景茅特,這里介紹個(gè)小方法蟆沫,就是在app運(yùn)行之后,按home鍵退到后臺(tái)温治,然后打開(kāi)電腦命令行工具,運(yùn)行:

  adb shell am kill 包名packagename

此時(shí)app就會(huì)被釋放,接著通過(guò)任務(wù)管理器或者啟動(dòng)圖標(biāo)打開(kāi)app戒悠,這個(gè)時(shí)候剛剛的界面就會(huì)重建走onRestoreInstanceState了熬荆。


app調(diào)用系統(tǒng)相機(jī)后,拍照返回崩潰

一般情況下绸狐,我們大部分情況是通過(guò)傳遞uri的方式來(lái)調(diào)用系統(tǒng)相機(jī)的:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mTakePhotoUri = FileUtils.getOutputMediaFileUri(FileUtils.MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mTakePhotoUri);
                startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

這種通過(guò)指定uri存儲(chǔ)路徑的方式調(diào)用系統(tǒng)相機(jī)的方式

在onActivityResult的時(shí)候卤恳,返回的intent會(huì)沒(méi)有數(shù)據(jù)

因此我們一般都是在onActivityResult里獲取之前保留的uri(例子中的mTakePhotoUri累盗,這個(gè)變量是個(gè)全局變量)變量來(lái)獲取具體圖片文件。

正式因?yàn)檫@個(gè)問(wèn)題突琳,導(dǎo)致不管調(diào)用系統(tǒng)相機(jī)導(dǎo)致app退到后臺(tái)被釋放
還是三星之類(lèi)的手機(jī)調(diào)用相機(jī)時(shí)的自動(dòng)旋轉(zhuǎn)
都會(huì)導(dǎo)致調(diào)用相機(jī)的界面被釋放并重建若债,從而使得Activity界面的全局變量值丟失。

如果沒(méi)有在onSaveInstanceState里保存這個(gè)全局變量拆融,在onRestoreInstanceState取回mTakePhotoUri的值蠢琳,那重建之后的界面變量就丟失了,因此onActivityResult中取到的mTakePhotoUri就為null了镜豹,從而導(dǎo)致獲取圖片路徑變量的時(shí)候報(bào)null傲须。

經(jīng)過(guò)測(cè)試,經(jīng)過(guò)這樣的處理后趟脂,大部分相機(jī)的崩潰問(wèn)題都得以解決泰讽。

其實(shí)不僅是相機(jī),很多功能在實(shí)際開(kāi)發(fā)過(guò)程中都可能遇到因界面被釋放導(dǎo)致變量數(shù)據(jù)丟失的情況昔期,所以我們需要在onSaveInstanceState方法中根據(jù)實(shí)際情況來(lái)保存需要的變量已卸,在onRestoreInstanceState方法中取回變量。

當(dāng)然如果覺(jué)得太麻煩硼一,這里給大家推薦一個(gè)懶人庫(kù)累澡,可以自動(dòng)保存我們的變量,非常方便

https://github.com/frankiesardo/icepick


在Android 4.1等設(shè)備上使用EventBus報(bào)caused by: java.lang.ClassNotFoundException: Didn’t find class “android.os.PersistableBundle” on path: DexPathList

這個(gè)問(wèn)題我只在Android 4.1的設(shè)備上發(fā)生過(guò)欠动,在其他設(shè)備上均未報(bào)錯(cuò)

而造成這個(gè)錯(cuò)誤的原因是我在無(wú)意中重寫(xiě)了 onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) 這個(gè)方法
(正常情況下應(yīng)該重寫(xiě) onSaveInstanceState(Bundle outState)

如果你的手頭沒(méi)有4.1的設(shè)備永乌,這個(gè)問(wèn)題可能一直發(fā)現(xiàn)不了


引入圖片框架fresco后,出現(xiàn)is 32-bit instead of 64-bit的錯(cuò)誤

這個(gè)問(wèn)題主要由于Android系統(tǒng)對(duì)于so文件的加載機(jī)制造成的

不同CPU架構(gòu)的手機(jī)加載時(shí)會(huì)在libs下找自己對(duì)應(yīng)的目錄具伍,從對(duì)應(yīng)的目錄下尋找需要的.so文件翅雏;如果沒(méi)有對(duì)應(yīng)的目錄,就會(huì)去armeabi下去尋找人芽,如果已經(jīng)有對(duì)應(yīng)的目錄望几,但是如果沒(méi)有找到對(duì)應(yīng)的.so文件,也不會(huì)去armeabi下去尋找了萤厅。

我的項(xiàng)目只引用armeabi和 x86架構(gòu)的so文件橄抹,這里我們假設(shè)為lib.so文件

當(dāng)我使用一臺(tái)arm64-v8架構(gòu)的手機(jī)時(shí),因?yàn)檎也坏絘rm64-v8對(duì)應(yīng)的目錄惕味,因此系統(tǒng)會(huì)降級(jí)到armeabi中去查找lib.so文件楼誓。

而fresco圖片框架因?yàn)榭紤]到了so的兼容性,compile引入編譯的時(shí)候自帶了arm64-v8的so文件名挥,因此產(chǎn)生了一個(gè)arm64-v8的目錄疟羹。

當(dāng)項(xiàng)目打包編譯安裝后,arm64-v8架構(gòu)的手機(jī)因?yàn)椴檎业搅薬rm64-v8的目錄,因此所有的so文件都會(huì)到arm64-v8的目錄下查找榄融,不會(huì)再去查找armeabi目錄参淫,而在arm64-v8的目錄下,我并沒(méi)有配置對(duì)應(yīng)的lib.so文件愧杯,所以找不到lib.so文件涎才,隨即拋出is 32-bit instead of 64-bit的錯(cuò)誤。

那我們?nèi)绾谓鉀Q了力九,這里介紹三種方法:

  1. 為項(xiàng)目已經(jīng)引用的so庫(kù)添加對(duì)應(yīng)arm64-v8架構(gòu)的so庫(kù)耍铜,對(duì)于沒(méi)有源碼的情況下很難去配置編譯對(duì)應(yīng)版本的so文件;

  2. 刪除引用的庫(kù)的arm64-v8目錄的so文件畏邢;

  3. 在gradle的defaultConfig中設(shè)置

ndk {
    // 設(shè)置支持的 SO 庫(kù)構(gòu)架业扒,注意這里要根據(jù)你的實(shí)際情況來(lái)設(shè)置
    abiFilters 'armeabi' , 'x86'
}

這樣就固定只會(huì)打包armeabi和x86目錄的so文件了,這么做可以防止在使用不熟悉的庫(kù)的時(shí)候不小心引入了其他目錄的so文件造成app報(bào)錯(cuò)


Android app的實(shí)際開(kāi)發(fā)過(guò)程中還有各種各樣奇怪的問(wèn)題舒萎,如果你也遇到了一些特殊或者奇葩的bug程储,歡迎進(jìn)行補(bǔ)充

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市臂寝,隨后出現(xiàn)的幾起案子章鲤,更是在濱河造成了極大的恐慌,老刑警劉巖咆贬,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件败徊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掏缎,警方通過(guò)查閱死者的電腦和手機(jī)皱蹦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)眷蜈,“玉大人沪哺,你說(shuō)我怎么就攤上這事∽萌澹” “怎么了辜妓?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)忌怎。 經(jīng)常有香客問(wèn)我籍滴,道長(zhǎng),這世上最難降的妖魔是什么榴啸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任孽惰,我火速辦了婚禮,結(jié)果婚禮上鸥印,老公的妹妹穿的比我還像新娘勋功。我一直安慰自己腥例,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布酝润。 她就那樣靜靜地躺著,像睡著了一般璃弄。 火紅的嫁衣襯著肌膚如雪要销。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天夏块,我揣著相機(jī)與錄音疏咐,去河邊找鬼。 笑死脐供,一個(gè)胖子當(dāng)著我的面吹牛浑塞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播政己,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼酌壕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了歇由?” 一聲冷哼從身側(cè)響起卵牍,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沦泌,沒(méi)想到半個(gè)月后糊昙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谢谦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年释牺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片回挽。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡没咙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厅各,到底是詐尸還是另有隱情镜撩,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布队塘,位于F島的核電站袁梗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏憔古。R本人自食惡果不足惜遮怜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸿市。 院中可真熱鬧锯梁,春花似錦即碗、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至合敦,卻和暖如春初橘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背充岛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工保檐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人崔梗。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓夜只,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蒜魄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扔亥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,114評(píng)論 25 707
  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-androi...
    eddy_wiki閱讀 3,267評(píng)論 0 20
  • 初識(shí)Activity: 我們都知道android中有四大組件(Activity活動(dòng)权悟,Service服務(wù)砸王,Conte...
    wangling90閱讀 968評(píng)論 2 2
  • [TOC]前言:上個(gè)月抱著想換工作的心態(tài)谦铃,了解現(xiàn)在互聯(lián)網(wǎng)行業(yè)對(duì)求職者需求,順便了解下自己的水平榔昔,參加了幾個(gè)互聯(lián)網(wǎng)公...
    瀟瀟鳳兒閱讀 1,282評(píng)論 1 15
  • 原來(lái)當(dāng)自己用心的時(shí)候也可以去溝通驹闰,也可以去做很多事情,自己最近在工作版塊有些為自己著急了撒会,快過(guò)年了嘹朗,同時(shí)自己來(lái)公司...
    靜陽(yáng)暖冬閱讀 106評(píng)論 0 0