實習的第一周,剛開始的一些準備工作做的很累,拉行李,背東西,簽合同,搬房子......上班第一周的感受是超開心的,哥哥姐姐和叔叔阿姨們。。都很好,雖然我什么都不會,但大家都很熱心的幫助我,十分感動。。
學習
主要包括:
- 0.認識到看源碼的重要性......
- 1.Activity的生命周期和其他一些方法
- 2.入門屏幕旋轉的適配問題(人生第一個工作任務hhh)
- 3.如何從什么都不會開始看一個工程
- 4.了解和突擊
看源碼很重要......
大佬們說要有看源碼的習慣,里面什么都有......之前在學校時候自己也點進去看過,主要是由于一些邏輯也確實看不懂,看這個方法的內容,然后又要點到父類的,父類又點到父類里面沒有盡頭。。然后有些數據類型又沒見過,又要去看那個類...總之就是不可能就看個單獨這一塊,它和其他地方有千絲萬縷的關系,其他地方又有看不懂的,所以最后結果往往不如不看源碼了,去看別人總結過的東西。
這周開始嘗試著先看看注釋,不懂就先放下....然后發現很多網上的文章,還有一些書上的介紹其實大部分來自于源碼,有些人甚至就是把源碼的注釋翻譯了一遍。感覺這很快樂.....以后有時間要多看看(雖然還是什么都看不懂hhhh)....
為了強調閱讀源碼的重要性,下面一些學習內容會直接引用源碼的內容~
Activity的生命周期和其他一些方法
之前對單個活動的經典的生命周期作過了解。如下圖從上到下。
[圖片上傳失敗...(image-d075d8-1543204313407)]
- 完整——onCreate()到onDestroy(),onCreate初始化,onDestroy中釋放資源
- 可見——onStart()到onStop(),能看到,但用戶和程序不能交互
- 可交互——onResume()到onPause(),能看到,并且點了有反應
當然再加一個onRestart()是活動再次回到前臺時候回調的方法。
下面是要知道的其他知識。
1.onSavaInstanceState
,不屬于生命周期方法,用于狀態保存
- 調用時機: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,而是由于某些情況的出現,系統會認為它may be killed,所以調用這個方法來保存狀態,以便在真正被殺死之后,重建能夠恢復狀態,有這樣一些時機它一定會被調用:
- 當用戶按下HOME鍵時。
- 長按HOME鍵,選擇運行其他的程序時。
- 按下電源按鍵(關閉屏幕顯示)時。
- 從當前activity A中啟動一個新的activity時(如果A的生命周期)。
- 橫豎屏切換
....
該方法調用在onStop
之前,但和onPause
沒有時序關系
2.onRestoreInstanceState
,不屬于生命周期方法,用于重建時狀態恢復
- 調用時機
Activity被重新創建時,調用onRestoreInstanceState
(該方法在onStart之后),將onSavaInstanceState
保存的Bundle對象作為參數傳到onRestoreInstanceState
與onCreate
方法。
該方法調用在onStart
之后。這個方法只是可能調用,onSaveInstance
調用之后,如果這個活動并沒有重建,它是不會被調用的。
onRestoreInstanceState
和onCreate
恢復數據的區別: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.
參考這個討論:兩個區別
舉例——屏幕旋轉生命周期:第一次創建onCreate -> onStart -> onResume->onPause -> 保存狀態onSaveInstanceState -> onStop -> 銷毀onDestroy -> 重新創建onCreate -> onStart -> 恢復之前保存的狀態onRestoreInstanceState -> onResume
再次強調源碼的重要性。。上面兩個方法源碼注釋中什么都有。。
3.onConfigurationChanged
- 調用時機: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
屬性,指定誰,誰變了就不會重建這個活動,而是去調用這個方法。這些屬性可選值直接看文檔即可,包含了一些例如orientation,keyboard還有各種size等等。沒有指定的屬性,如果發生變化,那么the system will stop and restart the activity (to have it launched with the new configuration).
屏幕旋轉的適配問題
小萌姐分配這個屏幕適配任務給我時候,去搜了許多東西出來去看,看了很多有關dp,還有不同屏幕,不同分辨率的適配方案,自己也學了學。但是最后發現一開始有些緊張。。并沒有聽清楚我到底要干什么,實際上第一份任務的重點在于屏幕橫豎屏切換還有使用平板時候的適配。
這是個啥?
1.手機屏幕有兩種模式,橫屏和豎屏,如果不做任何處理,那么手機屏從豎屏轉換到橫屏時候,界面上展示的內容可能就會被拉長到變形,看上去很不舒服。
2.設備還有平板,平板本身屏幕比較大,不管橫屏豎屏,可能如果用手機豎屏的那種布局就不是很適合。
3.另外生命周期那里提到,橫豎屏切換會導致Activity重建,那么有些控件里面有些內容如果不加處理,重建后就會丟失,假設屏幕旋轉前,用戶正在手機上填寫一個注冊表單,如果處理不當,用戶會發現旋轉后的表單變成空白的了,嚴重影響使用體驗。如何解決?
1.直接限定Activity不能轉屏,手機上試了一下微信QQ都轉不動~兩種方法。
- 指定activity的
android:screenOrientation
屬性,portrait
為保持豎屏,landscape
為保持橫屏, - JAVA代碼中在setContentView之前指定
//設置豎屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//設置橫屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
2.但是還是想轉一轉....
就以這個為例:
下面是有嘗試過的一些方法....
- 重新寫一個布局
新建layout-land
和layout-port
文件夾,加上限定符(land就是橫屏,port就是豎屏),分別寫個布局(同名,比如都是activity_main.xml)放在里面,這樣不同屏幕模式下setContentView
就會去用對應的layout。 - 改變原來布局的屬性
橫豎屏切換會重建Activity,這樣有些數據可能會丟失,為了不讓重建,這個案例里面,橫豎屏的布局內容基本是一樣的,所以也沒有必要去寫兩個文件,只需要改變原來布局的一些屬性就好了,就用到上面提過的onConfigurationChanged
相關內容,指定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
,但是卻出現了轉型異常,參見這里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的其他東西有點多后面再看源碼。現在就是知道先調用控件的get得到params,再調用params的set去設置想要的屬性,然后再用控件的setLayoutParams
設置回去。
最后修改主工程轉是轉過來了,但是遇到了上面那個view的圖片失真了,變得很難看....也不知道什么原理。下周再學~
如何從什么都不會開始看一個工程
什么都不會,各種沒見過的框架,沒見過的設計模式,看不太懂的一些寫法,還有新語言。。
目前感覺一個比較能接受的方法是在手機上打開app,邊點進各個界面,邊去看代碼,同時在布局預覽中看布局里面有哪些View,在什么位置上,各個fragment等等,然后去看代碼里面的具體邏輯。
就以目前正在看的東西為例:
1.去AndroidManifest.xml里去查一下intentfilter看一下啟動的第一個活動是什么,手機上打開app也跟著走;
2.發現是個SplashActivity,閃屏頁面,點進去看看有些啥。
3.里面能看懂知道一些handler,設置了些布局,Intent,然后根據LayoutId點進去看看里面都有什么view,在什么位置。看不懂的看看注釋就先放下了,不可能一上來就看懂...還重寫了BaseBindingActivity的一些方法,那自然也點進去看看Base里面有些什么東西。
4.閃屏過后手機已經進入到主界面了,這個界面在哪里....在SpalshActivity中發現了個toNextActivity()
方法,里面有:
IntentManager.startMainActivity(SplashActivity.this);
那就是跳到MainActivity了。接著再去看看MainActivity。
5.手機上點一點,然后代碼里找一找在什么地方,跳轉到什么位置了,重復上面的步驟。。。
大概就這樣。雖然還是看不懂很多。。但好一些了....
了解和突擊
1.了解了一下ButterKnife是個啥,就是不用一個個去findViewById,不用各種setClick等等。其它高級用法也看了看,用到再說。
2.學了學計算機組成原理準備期末考試,這里就不寫了....
其它
1.吃的很好,在外面上學六年以來吃的最好的一段時間了;
2.簽了租房合同,離公司班車點很近,擠地鐵很爽;
3.見了在北京的同學們,小白帶著去清華的食堂吃了飯,參觀了個校內的藝術展,感慨了一下真世界一流大學和偽世界一流大學的差距;