实习的第一周,刚开始的一些准备工作做的很累,拉行李,背东西,签合同,搬房子......上班第一周的感受是超开心的,哥哥姐姐和叔叔阿姨们。。都很好,虽然我什么都不会,但大家都很热心的帮助我,十分感动。。
学习
主要包括:
- 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.见了在北京的同学们,小白带着去清华的食堂吃了饭,参观了个校内的艺术展,感慨了一下真世界一流大学和伪世界一流大学的差距;