程序员自我救赎

记录程序员救赎之道

两年的时间,在这里成长,今天是在世景的最后一天,心中难掩不舍,虽然是一个集团大家庭,没有小公司的浓厚氛围,我想我是一个比较理性带有感性的人。两年,是一个不长不短的日子,感谢公司给与我这个工作机会。

在世景的两年里,我所骄傲的是我的Android能力的提高,世景给了我富足的时间让我学习、自我提高,在社区上分享了自己的轮子,得到了不少行内的认同和鼓励,学习了IOS开发,让我对移动开发的认识进一步的提高。

祝福世景

每周三晚的技术分享和每周末每人一篇的技术博客

产品层面

  1. 特效的运用要考虑用户的心理趋向和感受,炫的效果很酷,可能会让人产生某种心理导向。
  2. 特效的运用要考虑将来功能的扩展,一味的渲染也不一定很好,可能会为后续功能带来难度。
  3. 一个产品能帮助用户解决至少一个问题,那解决问题会有主流程,引导要强化,比如按钮大,颜色显眼,字体稍大,放置位置移动少。
  4. 产品不能为照顾运营而偏离主题,或者严重影响美观和主要功能,聚划算妹纸儿们说广告banner曝光度不够,设计变为由轮转变为平铺,但是广告良莠不齐,视觉效果不好,并且主页list仅能显示1、2个商品,影响了主题功能。

 

代码方面

代码需要审核,程序的代码需要共同学习,完善代码  

项目方面

  1. 计划进度,前紧后慢,提前实施。
  2. 不拘泥与细节,不干扰整体进度。
  3. 个人有担当,能者多劳,最大程度保证进度。
  4. 有问题不能包着,有些项目问题不是一个人的问题,不是一人能担得住的。
  5. 宝不能压在责任无关人身上,别人的资源、承诺要充分利用,但是最终还是靠自己突破。
  6. 干一样活的人放在一起,沟通迅速,快速解决问题。
  7. 早上碰一下,清晰任务;晚上碰一下一下,检查进度。
  8. bug先把基础性、功能性问题解决,适配、显示、兼容问题靠后。
  9. 不同网络机型下的跑测,不同网络环境下的测试提前入测。
  10. 写完一天代码,尽量坚持用findbugs查找潜在危险。
  11. 同一版本多次发布,或多个版本发布后,记录下的crash问题如果没有版本属性就很难定位,混淆map也对应不上。发板后立即封代码,保证bug日志中的bug发生行数和源码一致。
  12. 开发新功能、打包、发布过程规范化,规范减少问题发生概率。
  13. 日志规范:
            1). 冗长、惯例日志打到Verbose级别,例如网络返回信息,经常携带大量的信息,会严                                    重干扰视觉;
            2). 细粒度信息打到Debug级别,对出问题时调试有帮助作用,比如某个参数的值,我并    不总想知道是多少,但某些情况我就得看一下;
            3). 粗粒度级别信息打到Info级别,比如应用业务主逻辑,运行中重要的过程或关键点;
            4). 会出现 潜在错误的信息 或者 可以接受的错误 打到Warn级别,比如某个地方我想警告一下说这里是有问题的,或者可能引出其他什么问题;
            5). 错误或者致命信息,理应放到Error级别,血红的颜色很显眼~

 

管理方面

  1. 会议总结问题,就一定要着手解决,不解决会议时间就白浪费了。
  2. 对于人的期望,快速的给予回馈,帮助其向希望的方向发展。

1
2
3
4
5
6
7
8
9
android{
...
defaultConfig {
...
ndk {
abiFilters 'armeabi', 'x86'//, 'armeabi-v7a', 'x86_64', 'arm64-v8a', mips, mips64...加入需要生成的文件夹
}

}

如果不添加此处ndk的选项描述,那么androidstudio默认打包会产生所有的平台so文件包,如果没有相应的so文件那么就会导致程序报错:找不到so文件在某个目录下。因此我们需要根据现有的什么类型的so文件进行配置ndk。

  • 通常我们都会有armeabi和x86平台的so文件,这两个都是为32位的平台提供。有这两个就满足的几乎全部的机型了
  • armeabi-v7a,arm64-v8a都是arm平台的更优化的平台,使用这个so文件效率更高,如果有这种的so文件那么就添加响应的配置。
  • 手机优先选择平台更好的处理平台的so文件,因此没有高版本的so文件就不要添加配置。

####如何把库发布到JCenter

1、首先去注册https://bintray.com
2、

1
2
3
4
5
6
7
8
9
10
11
12
13
 classpath 'com.novoda:bintray-release:0.3.4'

如果遇到错误添加
allprojects {
repositories {
jcenter()
}
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
}
}

3、库的build

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apply plugin: 'com.novoda.bintray-release'//添加
android {
lintOptions {
abortOnError false
}
}

publish {
userOrg = 'limxing'//bintray.com用户名
groupId = 'me.leefeng'//jcenter上的路径
artifactId = 'library'//项目名称
publishVersion = '1.0.2'//版本号
desc = '我的个人库,更改动画'//描述,不重要
website = 'https://github.com/limxing/app'//网站,不重要;尽量模拟github上的地址,例如我这样的;当然你有地址最好了
}

在最近的项目中,使用了ViewPager+ImageView进行图片的浏览,OOM的代码:

1
2
3
4
5
6
7
@Override
public Object instantiateItem(ViewGroup container, int position) {
Work.Att att = list.get(position);
PhotoView view = new PhotoView(container.getContext());
container.addView(view);
return view;
}

这样会重复的创建ImageView,可能没有被回收,所以解决的方案是创建一个全局的集合,让图片都放进去,在使用的时候根据位置进行设置不同的图片去展示

1
2
3
4
5
6
7
@Override
public Object instantiateItem(ViewGroup container, int position) {
Work.Att att = list.get(position);
PhotoView view = Application.getImageList().get(position);
container.addView(view);
return view;
}

####关键

但是这样同样会让Viewpager指针指向了这个集合中的ImageView,因此在onDestory中添加:viewpager.removeAllViews();

在使用RecyclerView过程中使用 notifyItemInserted notifyItemRangeRemoved等
方法时,还要调用notifyItemRangeChanged(position,list.size());

1
2
3
4
5
list.add(0, "leefeng.me" + "==onRefresh");
recycleview.stopRefresh(b);
adapter.notifyItemInserted(0);
adapter.notifyItemRangeChanged(0,list.size());

在使用RadioButton的时候在选择图片切换的时候出现的一个问题:

1
2
<item android:drawable="@drawable/my_on" android:state_checked="true" />
<item android:drawable="@drawable/my_off" />

不能添加state_pressed的状态,否则就出现了不能够正常切换DrawableTop图片

Android ViewPager左右滑动取消的方法是重写子View
实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (getScrollX()<0) {
LogUtils.w("WifiCustomWebView---> getScrollX <= 0");
getParent().requestDisallowInterceptTouchEvent(false);
return false;
} else if (getScrollX() >= computeHorizontalScrollRange()) { //- getWidth()
LogUtils.w("WifiCustomWebView---> getScrollX >= computeHorizontalScrollRange()");
return false;
} else {
LogUtils.w(computeHorizontalScrollRange()+"--"+getScrollX()+"=="+"WifiCustomWebView---> true");
getParent().requestDisallowInterceptTouchEvent(true); //子view中,可以中断pager获取到事件
return true;
}
// return super.onInterceptTouchEvent(ev);
}
0%