来深圳了,对于这个沿海城市第一感觉就是:真的好热啊,下飞机一出机场眼镜马上上霜了,深圳真的是很热~~~情,也难怪了,赶上全国这几天的高温天气,真是伤不起,这让我一下回想起了当年在安徽上学时候的情景,可能也是适应南方的气候了吧,这次来深圳并没有太多的不适应,只有痘痘不太给力,来了之后疯狂爆痘,可能还是有些水土不服吧。
来了公司眼界真的不一样,人还是多出来走走好一些,在这里学习了好多新的框架,认识了好多牛人,这几周周算是在公司熟悉代码吧,周六帮公司修正了一个自定义View方面的BUG,也算是小有收获。
多的不说啦,总结一下这周都学到什么了吧
首先不得不说的就是公司现在android代码里用的基于apt技术的注入框架——Dagger了,不同于以往的RUNTIME注入框架,它是在Comile阶段注入到代码里的,对应用的整体性能没有影响。当然,从使用者的角度来说这可真是个让人又爱又恨的框架,用好了,可以显著提升代码的编写质量和维护性,要是用不好,代码简直是一团遭,不过我相信后期的话google肯定会优化这个问题的。其实从Dagger的使用者角度来看,如果在大型项目中使用,确实可以降低代码的耦合程度,当然,现在主流的大型项目都采用MVP架构进行设计,那么Dagger本身也是为了优化new一个对象所带来的紧耦合问题,将对象的引用和对象的实例化分开(简单的使用模式下@Inject和@Component),通过注入技术,降低了对象和引用之间的关联度。当然,在引用第三方库或者对象较多时,可以借助@Module进一步的将对象实例化提升一个档次,通过在@Module中定义需要实例化的对象,指定modules(可填写多个module),配合@Provider,可以很方便的管理对象的实例化,使得整个项目的层次更加清晰了,并且,对于实例化对象带参数的问题,Dagger也是一个非常有力的工具,以往,我们如果在实例化对象的过程中遇到带参的情况,且参数很多,深度很深的时候,写出来的代码往往有太多的括号和缩进,这样的写法会让很多Coder抓狂。但是通过APT技术,只需要在根参数的地方使用@Inject进行修饰,Dagger就可以自动帮你填入参数甚至是实例化啦,怎么样,有没有很方便呢?
最后一个@Scope,这个注解在项目中应用的相对来说少一些,不过鉴于他也是Dagger当中很重要的部分,也一并了解了。其实也没什么神秘的。这里我就引用之前看过的一篇博客里的内容了,地址会附在博文后面。
@Scope是用来管理依赖的生命周期的。
它和@Qualifier一样是用来自定义注解的,而@Singleton则是@Scope的默认实现。
/**
* Identifies a type that the injector only instantiates once. Not inherited.
*
* @see javax.inject.Scope @Scope
*/
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
Component会帮我们注入被@Inject标记的依赖,并且可以注入多个。
但是每次注入都是重新new了一个依赖。如
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Inject
Pot pot;
@Inject
Pot pot2;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerMainActivityComponent.builder()
.potComponent(DaggerPotComponent.builder()
.flowerComponent(DaggerFlowerComponent.create()).build())
.build().inject(this);
Log.d(TAG, "pot = " + pot.hashCode() +", pot2 = " + pot2.hashCode());
String show = pot.show();
Toast.makeText(MainActivity.this, show, Toast.LENGTH_SHORT).show();
}
}
打印的地址值不一样,是两个对象。D/MainActivity: pot = com.aitsuki.architecture.pot.Pot@240f3ff5, pot2 = com.aitsuki.architecture.pot.Pot@2c79118a
假设我们需要Pot对象的生命周期和app相同,也就是单例,我们需要怎么做?这时候就可以用到@Scope注解了。
它和@Qualifier一样是用来自定义注解的,而@Singleton则是@Scope的默认实现。
/**
* Identifies a type that the injector only instantiates once. Not inherited.
*
* @see javax.inject.Scope @Scope
*/
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
Component会帮我们注入被@Inject标记的依赖,并且可以注入多个。
但是每次注入都是重新new了一个依赖。如
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Inject
Pot pot;
@Inject
Pot pot2;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerMainActivityComponent.builder()
.potComponent(DaggerPotComponent.builder()
.flowerComponent(DaggerFlowerComponent.create()).build())
.build().inject(this);
Log.d(TAG, "pot = " + pot.hashCode() +", pot2 = " + pot2.hashCode());
String show = pot.show();
Toast.makeText(MainActivity.this, show, Toast.LENGTH_SHORT).show();
}
}
打印的地址值不一样,是两个对象。D/MainActivity: pot = com.aitsuki.architecture.pot.Pot@240f3ff5, pot2 = com.aitsuki.architecture.pot.Pot@2c79118a
假设我们需要Pot对象的生命周期和app相同,也就是单例,我们需要怎么做?这时候就可以用到@Scope注解了。
说完了Dagger我么再来谈谈自定义View吧
说道自定义View,应该说是无人不知无人不晓了,相信很多新入职的android开发同学都做的是界面相关的工作。我也不例外,从老大那里接手来的第一个修改Bug的任务就是调整view的相关参数,具体的就不说了,公司利益相关。
实现这个自定义view主要用到了以下几个类:
Paint,Canvas,Bitmap和View
作为自定义View,我们首先应该做的就是集成该类啦,集成完成后呢?当view每次重新绘制的时候回调用回调函数onDraw,当然,如果你要对view做相关操作的话应该重写View中的
setVisibility
setDrawingCacheEnabled
getMaskDrawingCache()
buildMaskDrawingCache()
等等的一些方法,具体重写哪些方法就看开发的需要了。
除了View,还有Paint类,Matrix类和Canvas类,顾名思义,Paint类是用来做画布的,Canvas类用来做画笔的,那Matrix又是什么鬼?为了弄清这个类的含义,我在网上百度了一番,其实说白了也没什么神秘的,就是一个矩阵计算,废话不多说,上图
matrix有两个构造函数,一个是无参的,另外一个是有参的,通过无参的构造函数构建的对象坐标原点是原点,有参的构造函数构建的坐标是以传进来的坐标为原点的。之后再通过post***方法或pre***方法实现矩阵的前乘和后乘,实现了bitmap的旋转,位移和缩放操作,最后一行的三个参数设计3D变换相关的操作,这个以后再说吧。
除了这些代码中的相关类,由于是第一周工作,又熟悉了一下git相关的用法,之前一直在GitHub上push了,感觉用法大同小异吧,只不过自己开发没那么多branch。