Android面试一天一题(6 Day)

作者: goeasyway | 来源:发表于2016-05-24 11:48 被阅读5669次

    面试多了,总会遇到一些奇葩的事情。有一次面试一家做航空娱乐系统开发的公司,老板是新加坡人。面试我的是一个小伙子,感觉是个小leader吧,很腼腆。他把我叫到一间堆满飞机坐椅和屏幕的办公室,只问了我两分钟就走了。问了几个很基础的问题,基础到我对他的问题完全没有印象。哥哥正在纳闷还有十八般武艺没有使呢,HR就来叫我去经理室,经理很爽快的问我要多少工资,要不要提成分红等问题,就说要等他的新加坡老板做决定。不到两分钟,经理的面试也经束了。全程都不带自我介绍的,我在软件园这片区这么有名了?

    第二天,新加坡老板给我打了电话,进行了一个简单的电话面试,双方答成了协义,算是通过了面试。之后HR就给我发了Offer。到这时候我都感觉很神奇,然后再回头去看看自己的简历,没有出奇的地方啊,看不出是高手啊,怎么对方这么爽快呢?也不多了解了解,我心里对这家公司也产生一些疑惑,没有过五关斩六将得到的offer总感觉不踏实。后来因为现今这家公司也发了offer,权衡了一下就没去。

    和新加坡老板电话道歉了,他感到很惋惜, 这是这么多次面试让我感到很无厘头的一次,有时真想去这家公司问问是怎么回事。

    好吧,故事讲完了,我们接着上一题,很多网友留言表示对View保存状态要设置ID这一点感兴趣。有网友提了这个问题:

    面试题:通过new创建的View实例它的onSaveStateInstance会被调用吗?

    这里再强调一下,自定义View控件的状态被保存需要满足两个条件:

    1. View有唯一的ID;
    1. 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要唯一的原因。

    如何解决这个问题呢?留给大家去展开吧,你是面试官的话,也可以留给来面试的人,不过这里太细节了建议最好做为附加题让对方试试(答不上不扣分)。

    相关文章

      网友评论

      • 哼哼傻逼验证码:所以我还是想知道最后应该怎么做,才能既有相同的ID,又可以保存不一样?
      • 李文臣:两个layout用的同一个sparseArray,设置成每个layout单独用一个sparseArray
      • 13号大王:关于最后的问题,我的思路是:既然一个界面中出现了两个Layout,那么这两个Layout就应该有属于自己的职能,两个完全相同职能的Layout在同一界面出现,这个界面本身的设计就存在问题,应该避免。
        既然两个Layout职能略有不同,那就把他们分别用两个XML表示。这样两个XML中的Subview就可以用不同的ID。

        这么做的优点是职责划分比较清楚,两个Layout井水不犯河水。缺点也是有的,那就是牺牲了一些复用性,不过考虑到App中同一Activity、Fragment中使用多个相同Layout的情况少之又少,就算有也只可能是两三个Layout,那其实并没有牺牲太多复用性,可以接受。
      • 望北8261:setSaveEnabled的注释

        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.
      • 天青色等煙雨_而我在等妳:博主有没有遇到过不顺利的面试啊?感觉博主好厉害,面试应该都不成问题吧。 :smiley:
        goeasyway:@天青色等煙雨_而我在等妳 面试别人面试多了,站的角度就不一样,不管是看法和经验都会得到提升,会更容易通过别人的面试吧。不过,别人非要问你的短板的话,不通过也是正常的。
      • one_cup:似乎只要设置不同的ID就可以了吧?不过这有点简单了,而且会遇到的很多情况都是需要具有相同ID的控件方便设置内容,这种情况下设置不同的ID就会在后续的工作中增加困难,想到一个方案也许可以改变SparseArray<Parcelable>中存放的key值,在进行保存之前对id值进行更改,恢复的时候再都变回来,不过感觉这样好像更麻烦,而且要深入了解保存的机制,研究一下 :smiley: 没有经过实践的都只是空想而已,试一试。
        one_cup:@天青色等煙雨_而我在等妳 比如聊天
        天青色等煙雨_而我在等妳:@one_cup “很多情况都是需要具有相同ID的控件方便设置内容”,我没遇到过这种场景,能说一下哪些场景需要这么做吗?
      • 0af700ea3d10:没有过五关斩六将的面试,感觉确实不靠谱
      • HuDP:原来是这样 相同layout 相同view如果没有id 系统恢复时无法区分 会恢复成最后那个
      • YungFan:知识很冷门哦 以前完全没想过 长知识
      • 柳轻言:请问怎么获取文中最后那幅图的子view状态?也就是SparseArray内的数据
        goeasyway:@柳轻言 不是很理解你要问的问题,你可以自己查看一下PhoneWindow.java内的saveHierarchyState()方法的源码,应该会有所了解。

      本文标题:Android面试一天一题(6 Day)

      本文链接:https://www.haomeiwen.com/subject/rtdvrttx.html