liujiangchuan / liujiangchuan/BlogAndroidCN

菜鸟起飞之路-Android开发总结(完)(博客搬家)

Open
#5 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
1
Forks
0
PR merge metrics
No merged PRs in 30d

Description

### 以下内容本人于2018/09/10 10:20在“OhwYaa|东软知识社区”平台首发,现整理到个人博客中。原址仅内部公开:https://www.ohwyaa.com/neusoft.com/blog/b58c6a7a-29bc-4abb-bb9c-350548f354fd/view/text

距离上一篇博文的发布已经快两年的时间了,这两年对Android技术的积累也确实有点少了,内容也相对旧了些。

**1. 编程基础**

1.1 虽然注解会影响性能,但也应该学习适当使用并理解其原理。

1.2 SimpleDateFormat 时间格式化的类,如果声明static全局变量,会有线程安全问题;如果每个线程都有一个sdf实例,频繁的创建和销毁,高并发下会耗费资源。使用ThreadLocal解决此问题。

1.3 NoClassDefFoundError 是类初始化失败,可能是构造函数中存在异常。

1.4 混淆文件中添加如下代码,可以屏蔽系统的log日志
```
# prohibit output log
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
```

1.5 在build.gradle中增加buildConfigField,则该值会增加到自动生成的BuildConfig.java类。
```
productFlavors
{
normal
{ buildConfigField 'String', 'API_BASE_URL', '"http://xxx.xx.com/"' }
test
{ buildConfigField 'String', 'API_BASE_URL', '"http://test.xx.com/"' }
}
```

1.6 分别添加 android.os.Debug.startMethodTracing() 和 android.os.Debug.stopMethodTracing() 方法来生成 trace 文件

1.7 lintOptions配置:
```
android {
lintOptions {
// true--关闭lint报告的分析进度
quiet true
// true--错误发生后停止gradle构建
abortOnError false
// true--只报告error
ignoreWarnings true
// true--忽略有错误的文件的全/绝对路径(默认是true)
//absolutePaths true
// true--检查所有问题点,包含其他默认关闭项
checkAllWarnings true
// true--所有warning当做error
warningsAsErrors true
// 关闭指定问题检查
disable 'TypographyFractions','TypographyQuotes'
// 打开指定问题检查
enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
// 仅检查指定问题
check 'NewApi', 'InlinedApi'
// true--error输出文件不包含源码行号
noLines true
// true--显示错误的所有发生位置,不截取
showAll true
// 回退lint设置(默认规则)
lintConfig file("default-lint.xml")
// true--生成txt格式报告(默认false)
textReport true
// 重定向输出;可以是文件或'stdout'
textOutput 'stdout'
// true--生成XML格式报告
xmlReport false
// 指定xml报告文档(默认lint-results.xml)
xmlOutput file("lint-report.xml")
// true--生成HTML报告(带问题解释,源码位置,等)
htmlReport true
// html报告可选路径(构建器默认是lint-results.html )
htmlOutput file("lint-report.html")
// true--所有正式版构建执行规则生成崩溃的lint检查,如果有崩溃问题将停止构建
checkReleaseBuilds true
// 在发布版本编译时检查(即使不包含lint目标),指定问题的规则生成崩溃
fatal 'NewApi', 'InlineApi'
// 指定问题的规则生成错误
error 'Wakelock', 'TextViewEdits'
// 指定问题的规则生成警告
warning 'ResourceAsColor'
// 忽略指定问题的规则(同关闭检查)
ignore 'TypographyQuotes'
}
}
```

**2. UI及资源**

2.1 `空格:  窄空格:  有点意思。`

2.2 软键盘显示的方法:
```
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
View view=getCurrentFocus();
if(null!=view) {
imm.showSoftInput(view,InputMethodManager.SHOW_FORCED);
}
```
showSoftInput的第二个参数为flag,0默认,2表示必须主动调用close方法才会关闭软键盘,例如activity销毁的时候,也不会关闭软键盘。

如果在onCreate和onResume()中执行将不起作用,因为布局必须要完成加载,可以通过postDelayed方式延迟执行。
```
getWindow().getDecorView().postDelayed(newRunnable() {
@Override public void run() {
openBoard();
}
},100);
```

2.3 设置对话框的属性

设置对话框的软键盘和主界面保持一致(unchanged),该方法必须在dialog.show方法后执行才生效。
```
WindowdialogWindow=getWindow();
dialogWindow.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.TOP);
WindowManager.LayoutParamslp=dialogWindow.getAttributes();
lp.y=y;
lp.softInputMode=WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
dialogWindow.setAttributes(lp);
```

2.4 RecyclerView 实现点击按钮后列表返回到顶部。
通过mGridLayoutManager.findFirstCompletelyVisibleItemPosition()方法,如果返回值>0,说明列表没在顶部,等于0说明在顶部。然后调用scrollToPosition(0)的方法返回顶部,注意调用后需要调用invalidate()方法,为了刷新滚动条显示位置,(这算是一个android的bug)。不要使用findFirstVisibleItemPosition()这个方法,也不要忘记invalidate()方法,否则当列表内容超过1屏但又不满两屏时,就会出现判断错误或滚动条位置不对的问题。

2.5 画虚线
```





```

关于4.0以上设备虚线会变实线的问题解决
代码中可以添加:
`line.setLayerType(View.LAYER_TYPE_SOFTWARE, null); `
xml中可以添加:
`android:layerType="software" `

**3. 经验**

3.1 数据库版本号提升,应该也升级APP的version code,这样当降级安装时,就会提示版本安装不上,而不会出现数据库降级的情况。

3.2 更新媒体库文件
以前做Kindle项目时,会碰到下载了新文件或删除文件之后,媒体库并没有更新,需要主动触发。
```
// 通知媒体库更新单个文件状态
Uri fileUri = Uri.fromFile(file);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,fileUri));
```
媒体库会在手机启动,SD卡插拔的情况下进行全盘扫描,不是实时的而且代价比较大,所以单个文件的刷新很有必要。

3.3 LeakCanary 信息获取
```
LeakCanary.install (application, LeakService.class, AndroidExcludedRefs.createAppDefaults().build());
public class LeakService extends DisplayLeakService {
@Override
protected void afterDefaultHandling(HeapDumpheapDump, AnalysisResultresult, StringleakInfo) {
super.afterDefaultHandling(heapDump, result, leakInfo);
NLog.d(LeakService.class.getName(), leakInfo);
saveResult(heapDump, result, leakInfo);
}
}

```
3.4 Glide 使用.into(new SimpleTarget())时,设置.error无效,可以在重写Target中的onLoadFailed方法。

3.5 封装网络请求接口时,考虑区分同一接口有可能有两种场景:前台及时响应的;后台非用户操作自动发送的。前台的接收异常码时可能会提示给用户;后台操作不会给提示,不会让用户感知。

3.6 编译错误:Error:Tag attribute name has invalid character '?'.
解决方法:注释掉项目工程中的gradle.properties 里面的android.enableAapt2=false

_至此,“菜鸟起飞之路”系列博文就收尾了,同时,我在东软的职业生涯也就此结束了。就不开放评论了,祝大家好运常伴。_

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the issue body, which contains a completed Chinese-language Android blog post and its original internal source link. No repository file, test, requested edit, or completion criterion is identified, so the needed change and definition of done must be clarified before work begins.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
content, documentation
Issue type
Documentation
Difficulty
1/5
Estimated time
Under an hour
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.