实习连载日记3.3-为了免费的饭而加班

#实习第二天

  • eventbus
  • getDim
  • FragmentTabHost
  • asyncTask.execute和AsyncTask.executeOnExecutor
  • 获取jsbridge白名单
  • 抛出IllegalStateException
  • isInEditMode()
  • ViewStub
  • onsaveinstancestate和onrestoreinstancestate

##杂谈模块:

相对于第一天看了很多源码。受益匪浅。

带老朽我回忆一番,今天。。。略有失忆。。。

好高兴啊,周五了,明天放假!但是我还是打算来,因为有免费的午餐和晚餐,我要不来公司的话,就要自己花钱买饭了。

这点挺服气公司的,拿吃这个弱点来引诱我来。

插:3.4日,修改帖子,另外插更一下周六的事,一群产品在加班!!!

都不认识我,因为我新来的,大眼瞪小眼的看着我,干嘛?没见过为了免费的吃的来加班的实习萌新吗?

产品在加班,什么意思呢?是要让在周一的时候我老大和前辈们有活干啊,产品,好心机的与程序员相爱相杀的一群人!

相爱相杀这个词是一个学姐说的,据她所说,大学时没好好学编程,毕业就做了产品。

然而在程序员眼里,程序员和产品,没有相爱,只有相杀。

午饭后和前辈散步,代沟出现了。前辈们都在商量着结婚,落户,购房等话题。那我呢?插不上嘴,对象都不知道出生没。。。

人在人生的不同的阶段会重点想着不同的事情,如果在早前的阶段想着后来的事情,这种人一般会很上进,但也会每天都杞人忧天,例如我。有些人在当下想着之前的事情,沉寂在过去,碌碌无为,例如:好多人。所以,人,一定要活在当下!

就拿我现在来说,之前几天还在想着游戏的事情,现在却在想着工作,毕业后怎么的事情,哦对了,还有,我会孤独一生吗?

##eventbus

·优点
·用法


###优点:

EventBus是一个事件发布/订阅总线,有效适用于Android系统平台。 组件之间的通信更加简单
针对在事件的发送者和订阅者之间进行解耦 非常好的运用在Activitys、Fragments和后台线程
避开了联系紧密易出错的依赖关系和容易出错生命周期 使你的代码更加简洁 快 瘦(小于50K的jar包)
有100,00,000+的app使用了EventBus


###用法:自己百度!
推荐:http://blog.csdn.net/harvic880925/article/details/40660137
不过这个有点老,最新的eventbus可以自己定义方法名字,写自己喜欢的,只要加上注解就可以了。


###原理:
#####getDefault():
获取一个eventbus实例,单例模式的方法。
#####几个poster:
用来post消息。

  • mainThreadPoster:
    继承自Handler,传递来一个Looper,创建主线程的Handler,通过sendmessage方式发送信息。在主线程中进行。
  • backgroundPoster:
    实现runnable接口,明显是提供子线程的方式来执行任务。调用eventBus.getExecutorService().execute(this)方法,将事件放在一个空闲的线程中执行。内部利用synchronized关键字,可线程同步,线程安全。在runnable接口中无限循环调用eventBus.invokeSubscriber(pendingPost);方法 ,使用反射调用订阅的者的事件。
  • asyncPoster :
    实现runnable接口,在子线程中执行任务,调用eventBus.getExecutorService().execute(this)方法,将事件放在一个空闲的线程中执行。无synchroized关键字,线程不安全。在runnable接口中调用eventBus.invokeSubscriber(pendingPost)使用反射调用订阅的者的事件。
    #####订阅注册者原理:
  • 调用了subscriberMethodFinder对象的findSubscriberMethods(subscriberClass)方法获取一个存入SubscriberMethod的list。
  • subscriberMethodFinder就是一个管理工具,获取查找订阅者,订阅者Method的工具。
  • SubscriberMethod就是一个Method,封装了一下,内部重写了equals和hashcode。
  • findSubscriberMethods方法,是如何获取到订阅者的所有方法信息的?:
    逐步向下走判断非空等不赘述,最后通过反射机制获取所有方法的相关信息。最后在findUsingReflectionInSingleClass(findState)的调用方法处调用了
    return getMethodsAndRelease(findState);返回了出去了一个List集合。
  • register方法中:获取了SubscriberMethod的list后,遍历,调用subscribe(subscriber, subscriberMethod)来订阅。
  • subscribe(subscriber, subscriberMethod)原理:取出eventType,和Subcription相关联(具体关联的原理,目前的我还没精力去研究,粗略看一下,应该是这个方法:subscriptionsByEventType.get(eventType); ),同时处理一些sticky逻辑。
  • subcription就是封装了一个订阅者的bean。
post(Object event) 发布订阅事件原理
  • 获取当前正在post线程的PostingThreadState对象,通过这个对象获得事件队列,把我们要post的event实例add进去。如果没有事件posting,则调用postingState.canceled方法,取消当前post。如果事件队列不为空,则通过 postSingleEvent(eventQueue.remove(0), postingState)方法post队列中的第一个event。
  • postSingleEvent原理:
    通过lookupAllEventTypes(eventClass)方法将event.getclass存入list list名为eventtype,遍历list调用postSingleEventForEventType(event, postingState, clazz)方法。clazz就是list中每个子项,即,每个eventtype。
  • postSingleEventForEventType:通过clazz获取到subscriptions集合,遍历这个集合,每次都将事件赋值给poststate.event,将subcriptioins集合的当前子项给poststate.subscriptioin,通过方法 postToSubscription(subscription, event, postingState.isMainThread)完成发布订阅事件。将订阅者,事件,关联!
  • postToSubscription(subscription, event, postingState.isMainThread)方法判断传过来的模式,进行不同线程的执行。其中,ismainthread就是在主线程中,详见源码了,这很简单,还有background和async,还有一个默认的线程,就是当前线程。都是通过反射。没精力再向下看了。还涉及到线程池。
  • 原理参考自这个帖子,这个帖子也有不准的仁者见仁,反正也没什么用:http://blog.csdn.net/hua631150873/article/details/51377131

##getDim
getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别详解
只看了他们的表面上的区别,没看源码:
参考:http://blog.csdn.net/cnmilan/article/details/38339109


##FragmentTabHost
用法之类的就不说了,百度有好多,咱说的是:
FragmentTabHost切换Fragment时避免重复加载UI
方法简单,加个缓存view,并且每次切换回来时,要将缓存view移除,否则就会爆出当前view已有parent的错误。

private View rootView;//缓存Fragment view  
      
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
        if(rootView==null){  
            rootView=inflater.inflate(R.layout.tab_fragment, null);  
        }  
 //缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。  
        ViewGroup parent = (ViewGroup) rootView.getParent();  
        if (parent != null) {  
            parent.removeView(rootView);  
        }   
        return rootView;  
    }  

http://blog.csdn.net/jdsjlzx/article/details/41211395


##asyncTask.execute和AsyncTask.executeOnExecutor

execute单线程执行子任务,后者多线程并行,默认5个线程,可自定义。
详见:http://blog.csdn.net/kufeiyun/article/details/41477069,注意,里面的推荐链接也不错哦。


##获取jsbridge白名单
服务端和移动端定义好一个url,此url中为一个json,内有service字段以及domain和allow等,皆为白名单相关属性。
通过给定url获取jsonobject对象,将其object中service存为list,保存在sp中,在需要判断的地方,
调用判断方法,(在需要判断的页面获取网络上数据,就会有一个网络上的jsonobject以及list,从sp中取出list,遍历sp中list,
判断list中的allow这个list是否为空,
不为空再判断domain是否为给定值(移动端常量),或者当前页的网络中的host是否sp中domain结尾(转换为小写),
是则再判断sp中list中allow的第一个值是否和给定值(移动端常量)相同
实则返回true(为白名单)
或者判断sp中list中allow是否包含从网络获取的第一个value值,此value值从参数传来)


##抛出IllegalStateException
http://jingyan.baidu.com/article/b907e627ac77ac46e6891c5d.html
在某些自己封装的内部中,经常看到抛出这个异常,大多数是杂调用某个控件时,判断是否为空,是则抛出。


##isInEditMode()
看到包含一个自定义的loadingview,其中有isInEditMode方法。此方法作用:

源码注释翻译:
指示此视图当前是否处于编辑模式。当在开发工具中显示时,视图通常处于编辑模式。例如,如果该视图由可视化用户界面生成器绘制,则该方法应返回true。
如果子类的正常行为可能干扰宿主环境,子类应该检查该方法的返回值以提供不同的行为。例如:启动一个线程类的构造函数中,绘图代码依赖于设备的具体特点,等。
通常在自定义部件的绘图代码中检查此方法。
http://www.th7.cn/Program/Android/201504/440127.shtml
防止报错:可视化编辑物法报错?或Use View.isInEditMode() in your custom views to skip
code when shownin Eclipse

loadingview大致实现思路:
加载一个布局,布局中有正在加载的图标文字,有两个viewstub分别代表无数据和无网络时的图表与文字的layout。
正在加载的时候,调用loading方法,(若无数据或无网络的layout不为空,取消无数据和无网络layout的显示。)
无数据时调用noData方法,(如果无数据layout不为空,显示。否则,填充无数据stub,添加重试监听(都需要判断是否为空))
无网络一样


##ViewStub
刚刚写到这里时,浏览器崩溃,线上草稿这里又没保存,还要重写一遍,我现在正在用的浏览器是chrome。。。

当我们有这样一个需求的时候:在父布局中有两个子布局a和b,在A情况下,a布局可见,在B情况下,b布局可见。

*这时大多数会这样实现:*在父布局中把两个子布局都写上,并都设置为不可见,在代码中判断,当A情况时,a设为可见,b不可见,B情况时b设为可见,a不可见。但这样的话,在父布局加载(infalter)时,a和b也同时加载了,但如果程序运行时全程没有显示b的情况下,会造成内存以及cpu资源的浪费。于是乎,viewstub出现了。

ViewStub相当于一个占位符,他可以指定一个布局,这个布局在父布局加载的时候,不会同时加载。而是在需要的时候,在代码中加载(infalter)。
viewstub用法百度一下,全都出来。


##onsaveinstancestate和onrestoreinstancestate

  • 举例: 系统存在两个activity,a和b
    a先启动,然后打开b,当b被打开且位于a的上面时,(b将a覆盖),这时,a通过onsaveintancestate保存用户状态,
    将来用户返回a时,能通过oncreate或者onrestoreintancestate恢复。

  • 在onsaveinstancestate中,保存有view的数据,在一个parcelable对象中,并返回。
    在activity的onsaveinstancestate中,调用view的onsaveinstance方法,返回这个parcelable对象。
    然后用bundle的putparcelable方法,保存在bundle saceinstancestate中。
    当系统调用activity的onrestoreinstancestate方法时,通过bundle的getparcelable方法,获得parcelable对象,
    然后将其传给view的onrestoreinstancestate方法,在view中的onrestoreinstancestate中从parcleable读取数据,以便view使用。

  • onsaveinstancestate何时被调用
    当此activity很容易被销毁时,即当此activity被用户至于后台时,系统不知道用户接下来会运行多少程序,以及此activity是否会被销毁,这时,调用此方法。
    例如:按下home键,长安home键,打开其他activity等等。。。

  • onrestoreinstancestate何时被调用 activity确实被销毁了,此时用户返回此activity
    onsaveinstancestate被调用了,onrestoreinstancestate不一定被调用,onrestoreinstancestate被调用了,onsaveinstancestate一定被调用。
    onrestoreinstancestate在onstart和onpostcreate之前调用。

  • 持久化保存数据不应该用onsaveinstancestate方法,应该在onpause,onstop中。保存额外数据时需要重写onsaveinstancestate。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值