面试多了,总会遇到一些奇葩的事情。有一次面试一家做航空娱乐系统开发的公司,老板是新加坡人。面试我的是一个小伙子,感觉是个小leader吧,很腼腆。他把我叫到一间堆满飞机坐椅和屏幕的办公室,只问了我两分钟就走了。问了几个很基础的问题,基础到我对他的问题完全没有印象。哥哥正在纳闷还有十八般武艺没有使呢,HR就来叫我去经理室,经理很爽快的问我要多少工资,要不要提成分红等问题,就说要等他的新加坡老板做决定。不到两分钟,经理的面试也经束了。全程都不带自我介绍的,我在软件园这片区这么有名了?
第二天,新加坡老板给我打了电话,进行了一个简单的电话面试,双方答成了协义,算是通过了面试。之后HR就给我发了Offer。到这时候我都感觉很神奇,然后再回头去看看自己的简历,没有出奇的地方啊,看不出是高手啊,怎么对方这么爽快呢?也不多了解了解,我心里对这家公司也产生一些疑惑,没有过五关斩六将得到的offer总感觉不踏实。后来因为现今这家公司也发了offer,权衡了一下就没去。
和新加坡老板电话道歉了,他感到很惋惜, 这是这么多次面试让我感到很无厘头的一次,有时真想去这家公司问问是怎么回事。
好吧,故事讲完了,我们接着上一题,很多网友留言表示对View保存状态要设置ID这一点感兴趣。有网友提了这个问题:
面试题:通过new创建的View实例它的onSaveStateInstance会被调用吗?
这里再强调一下,自定义View控件的状态被保存需要满足两个条件:
- View有唯一的ID;
- View的初始化时要调用setSaveEnabled(true) ;
简单看一下View状态保存和读取的调用过程:
里面的SparseArray(完整的参数是:SparseArray<Parcelable> )是一个KEY-VALUE的Map,KEY当然就是View的ID了。所以细看一下源码的调用过程,你一下就理解为什么一定要给View调置一个唯一的ID了。
那好,现在回答上这个网友的问题“通过new创建的View实例它的onSaveStateInstance会被调用吗?”,答案还是一样的如果设置了ID就会。其实我们在XML文件中配置的布局和属性最终都是通过LayoutInflater中的inflate方法去加载,由它去创建各个View的实例(还是用new),并根据XML文件中的属性设置相关的值。
我们再展开一下,如果我们定义了一个自义的Layout,在同一个界面中引用了两次这个自定义的Layout(如下图的myLayout1 & myLayout2),那么它的状态会发生什么情况呢?
我们会发现两个Layout的状态被保存了,但Layout中的每个子View状态是相同的,被最后一个保存的View覆盖了。这也是为什么我们要强调View的ID要唯一的原因。
如何解决这个问题呢?留给大家去展开吧,你是面试官的话,也可以留给来面试的人,不过这里太细节了建议最好做为附加题让对方试试(答不上不扣分)。
网友评论
既然两个Layout职能略有不同,那就把他们分别用两个XML表示。这样两个XML中的Subview就可以用不同的ID。
这么做的优点是职责划分比较清楚,两个Layout井水不犯河水。缺点也是有的,那就是牺牲了一些复用性,不过考虑到App中同一Activity、Fragment中使用多个相同Layout的情况少之又少,就算有也只可能是两三个Layout,那其实并没有牺牲太多复用性,可以接受。
Controls whether the saving of this view's state is enabled (that is, whether its onSaveInstanceState() method will be called). Note that even if freezing is enabled, the view still must have an id assigned to it (via setId(int)) for its state to be saved. This flag can only disable the saving of this view; any child views may still have their state saved.