實習的第一周,剛開始的一些準備工作做的很累,拉行李,背東西,簽合同,搬房子......上班第一周的感受是超開心的,哥哥姐姐和叔叔阿姨們。。都很好,雖然我什么都不會,但大家都很熱心的幫助我,十分感動。。
學習
主要包括:
- 0.認識到看源碼的重要性......
- 1.Activity的生命周期和其他一些方法
- 2.入門屏幕旋轉(zhuǎn)的適配問題(人生第一個工作任務(wù)hhh)
- 3.如何從什么都不會開始看一個工程
- 4.了解和突擊
看源碼很重要......
大佬們說要有看源碼的習慣,里面什么都有......之前在學校時候自己也點進去看過,主要是由于一些邏輯也確實看不懂,看這個方法的內(nèi)容,然后又要點到父類的,父類又點到父類里面沒有盡頭。。然后有些數(shù)據(jù)類型又沒見過,又要去看那個類...總之就是不可能就看個單獨這一塊,它和其他地方有千絲萬縷的關(guān)系,其他地方又有看不懂的,所以最后結(jié)果往往不如不看源碼了,去看別人總結(jié)過的東西。
這周開始嘗試著先看看注釋,不懂就先放下....然后發(fā)現(xiàn)很多網(wǎng)上的文章,還有一些書上的介紹其實大部分來自于源碼,有些人甚至就是把源碼的注釋翻譯了一遍。感覺這很快樂.....以后有時間要多看看(雖然還是什么都看不懂hhhh)....
為了強調(diào)閱讀源碼的重要性,下面一些學習內(nèi)容會直接引用源碼的內(nèi)容~
Activity的生命周期和其他一些方法
之前對單個活動的經(jīng)典的生命周期作過了解。如下圖從上到下。
[圖片上傳失敗...(image-d075d8-1543204313407)]
- 完整——onCreate()到onDestroy(),onCreate初始化,onDestroy中釋放資源
- 可見——onStart()到onStop(),能看到,但用戶和程序不能交互
- 可交互——onResume()到onPause(),能看到,并且點了有反應(yīng)
當然再加一個onRestart()是活動再次回到前臺時候回調(diào)的方法。
下面是要知道的其他知識。
1.onSavaInstanceState,不屬于生命周期方法,用于狀態(tài)保存
- 調(diào)用時機:This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. 什么情況算may be killed,簡單來說就是并不是用戶主動按下BACK去kill,而是由于某些情況的出現(xiàn),系統(tǒng)會認為它may be killed,所以調(diào)用這個方法來保存狀態(tài),以便在真正被殺死之后,重建能夠恢復狀態(tài),有這樣一些時機它一定會被調(diào)用:
- 當用戶按下HOME鍵時。
- 長按HOME鍵,選擇運行其他的程序時。
- 按下電源按鍵(關(guān)閉屏幕顯示)時。
- 從當前activity A中啟動一個新的activity時(如果A的生命周期)。
- 橫豎屏切換
....
該方法調(diào)用在onStop之前,但和onPause沒有時序關(guān)系
2.onRestoreInstanceState,不屬于生命周期方法,用于重建時狀態(tài)恢復
- 調(diào)用時機
Activity被重新創(chuàng)建時,調(diào)用onRestoreInstanceState(該方法在onStart之后),將onSavaInstanceState保存的Bundle對象作為參數(shù)傳到onRestoreInstanceState與onCreate方法。
該方法調(diào)用在onStart之后。這個方法只是可能調(diào)用,onSaveInstance調(diào)用之后,如果這個活動并沒有重建,它是不會被調(diào)用的。
onRestoreInstanceState和onCreate恢復數(shù)據(jù)的區(qū)別:it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation.
參考這個討論:兩個區(qū)別
舉例——屏幕旋轉(zhuǎn)生命周期:第一次創(chuàng)建onCreate -> onStart -> onResume->onPause -> 保存狀態(tài)onSaveInstanceState -> onStop -> 銷毀onDestroy -> 重新創(chuàng)建onCreate -> onStart -> 恢復之前保存的狀態(tài)onRestoreInstanceState -> onResume
再次強調(diào)源碼的重要性。。上面兩個方法源碼注釋中什么都有。。
3.onConfigurationChanged
- 調(diào)用時機:Called by the system when the device configuration changes while your activity is running. Note that this will only be called if you have selected configurations you would like to handle with the {@link android.R.attr#configChanges} attribute in your manifest.
在AM文件中去指定活動的android:configChanges屬性,指定誰,誰變了就不會重建這個活動,而是去調(diào)用這個方法。這些屬性可選值直接看文檔即可,包含了一些例如orientation,keyboard還有各種size等等。沒有指定的屬性,如果發(fā)生變化,那么the system will stop and restart the activity (to have it launched with the new configuration).
屏幕旋轉(zhuǎn)的適配問題
小萌姐分配這個屏幕適配任務(wù)給我時候,去搜了許多東西出來去看,看了很多有關(guān)dp,還有不同屏幕,不同分辨率的適配方案,自己也學了學。但是最后發(fā)現(xiàn)一開始有些緊張。。并沒有聽清楚我到底要干什么,實際上第一份任務(wù)的重點在于屏幕橫豎屏切換還有使用平板時候的適配。
這是個啥?
1.手機屏幕有兩種模式,橫屏和豎屏,如果不做任何處理,那么手機屏從豎屏轉(zhuǎn)換到橫屏時候,界面上展示的內(nèi)容可能就會被拉長到變形,看上去很不舒服。
2.設(shè)備還有平板,平板本身屏幕比較大,不管橫屏豎屏,可能如果用手機豎屏的那種布局就不是很適合。
3.另外生命周期那里提到,橫豎屏切換會導致Activity重建,那么有些控件里面有些內(nèi)容如果不加處理,重建后就會丟失,假設(shè)屏幕旋轉(zhuǎn)前,用戶正在手機上填寫一個注冊表單,如果處理不當,用戶會發(fā)現(xiàn)旋轉(zhuǎn)后的表單變成空白的了,嚴重影響使用體驗。如何解決?
1.直接限定Activity不能轉(zhuǎn)屏,手機上試了一下微信QQ都轉(zhuǎn)不動~兩種方法。
- 指定activity的
android:screenOrientation屬性,portrait為保持豎屏,landscape為保持橫屏, - JAVA代碼中在setContentView之前指定
//設(shè)置豎屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//設(shè)置橫屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
2.但是還是想轉(zhuǎn)一轉(zhuǎn)....
就以這個為例:

下面是有嘗試過的一些方法....
- 重新寫一個布局
新建layout-land和layout-port文件夾,加上限定符(land就是橫屏,port就是豎屏),分別寫個布局(同名,比如都是activity_main.xml)放在里面,這樣不同屏幕模式下setContentView就會去用對應(yīng)的layout。 - 改變原來布局的屬性
橫豎屏切換會重建Activity,這樣有些數(shù)據(jù)可能會丟失,為了不讓重建,這個案例里面,橫豎屏的布局內(nèi)容基本是一樣的,所以也沒有必要去寫兩個文件,只需要改變原來布局的一些屬性就好了,就用到上面提過的onConfigurationChanged相關(guān)內(nèi)容,指定Activity的android:configchanges屬性:
android:configChanges="orientation|keyboardHidden|screenSize"
重寫onConfigurationChanged方法,在方法中修改布局的margin屬性這里就讓margin左右各300dp。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setFrameLayout(newConfig.orientation);
}
private void setFrameLayout(int orientation){
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)frameLayout.getLayoutParams();
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
layoutParams.setMargins(0,0,0,0);
} else {
layoutParams.setMargins(300,0,300,0);
}
frameLayout.setLayoutParams(layoutParams);
}
這里就是涉及到了LayoutParams的一些東西,通過控件的getLayoutParams方法,這里那個fragment的容器是一個FrameLayout,本來以為返回的類型就是FrameLayout.LayoutParams,但是卻出現(xiàn)了轉(zhuǎn)型異常,參見這里getting-classcastexception-when-trying-to-insert-relativelayout-dyanmically
答案是The correct version of LayoutParams to instantiate depends on the parent of the view you're creating, not the type of the view itself.這里的父容器是個RelativeLayout,所以類型就是RelativeLayout.LayoutParams。LayoutParams的其他東西有點多后面再看源碼?,F(xiàn)在就是知道先調(diào)用控件的get得到params,再調(diào)用params的set去設(shè)置想要的屬性,然后再用控件的setLayoutParams設(shè)置回去。
最后修改主工程轉(zhuǎn)是轉(zhuǎn)過來了,但是遇到了上面那個view的圖片失真了,變得很難看....也不知道什么原理。下周再學~
如何從什么都不會開始看一個工程
什么都不會,各種沒見過的框架,沒見過的設(shè)計模式,看不太懂的一些寫法,還有新語言。。
目前感覺一個比較能接受的方法是在手機上打開app,邊點進各個界面,邊去看代碼,同時在布局預(yù)覽中看布局里面有哪些View,在什么位置上,各個fragment等等,然后去看代碼里面的具體邏輯。
就以目前正在看的東西為例:
1.去AndroidManifest.xml里去查一下intentfilter看一下啟動的第一個活動是什么,手機上打開app也跟著走;
2.發(fā)現(xiàn)是個SplashActivity,閃屏頁面,點進去看看有些啥。
3.里面能看懂知道一些handler,設(shè)置了些布局,Intent,然后根據(jù)LayoutId點進去看看里面都有什么view,在什么位置??床欢目纯醋⑨尵拖确畔铝?,不可能一上來就看懂...還重寫了BaseBindingActivity的一些方法,那自然也點進去看看Base里面有些什么東西。
4.閃屏過后手機已經(jīng)進入到主界面了,這個界面在哪里....在SpalshActivity中發(fā)現(xiàn)了個toNextActivity()方法,里面有:
IntentManager.startMainActivity(SplashActivity.this);
那就是跳到MainActivity了。接著再去看看MainActivity。
5.手機上點一點,然后代碼里找一找在什么地方,跳轉(zhuǎn)到什么位置了,重復上面的步驟。。。
大概就這樣。雖然還是看不懂很多。。但好一些了....
了解和突擊
1.了解了一下ButterKnife是個啥,就是不用一個個去findViewById,不用各種setClick等等。其它高級用法也看了看,用到再說。
2.學了學計算機組成原理準備期末考試,這里就不寫了....
其它
1.吃的很好,在外面上學六年以來吃的最好的一段時間了;
2.簽了租房合同,離公司班車點很近,擠地鐵很爽;
3.見了在北京的同學們,小白帶著去清華的食堂吃了飯,參觀了個校內(nèi)的藝術(shù)展,感慨了一下真世界一流大學和偽世界一流大學的差距;