从Android6.0开始,系统提供了两种省电功能(延长电池寿命和使用时间):Doze和App Standby Doze和App Standby模式会延缓CPU和网络活动实现节能;
Wake Locks
被无视;AlarmManager
被推迟到下一个maintenance window
窗口,
除非使用AlarmManager
新方法: setAndAllowWhileIdle(),setExactAndAllowWhileIdle(),setAlarmClock()
;进入App Standby模式 长时间未被用户使用的App,将进入App Standby状态(被标志为空闲状态)
Android6.0及更高版本提供电池优化白名单,App加入白名单可逃脱Doze和App Standby限制, 处于白名单中的App也会受到一定限制: Jobs和Syncs以及常规Alarms也会被推迟;
用户手动设置App进入白名单: 设置>电池>电池优化白名单
App检测是否在白名单: PowerManager.isIgnoringBatteryOptimizations()
App请求加入白名单:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) {
//1.进入系统电池优化设置界面,把当前APP加入白名单
//startActivity(new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
//2.弹出系统对话框,把当前APP加入白名单(无需进入设置界面)
//在manifest添加权限 <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
}
AlarmManager
失效(只有App进程在运行时,才会收到系统定时AlarmManager
通知)
添加守护进程,相互监听重启; 提醒用户加入锁屏清理白名单AlarmManager
任务失效
监听重启广播,重新设置定时闹钟setExact()
,setWindow()
,setAlarmClock()
;AlarmManager
被延缓
新增精确定时方法: setAndAllowWhileIdle()
,setExactAndAllowWhileIdle()
;从Android4.4(API19)开始,新增精准定时方法都是一次性闹钟,没有重复定时的方法, 所以当需要重复周期闹钟,只能在下一次唤醒时重新设置定时,间接实现重复闹钟。
精确定时一次Demo如下:
void setWakeAtTime(Context cxt, int delay) {
PendingIntent pi = PendingIntent.getService(cxt,0,new Intent(cxt, xxService.class),PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) cxt.getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) //Android 6,针对省电优化
alarm.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, pi);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) //Android 4.4,针对set不准确
alarm.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, pi);
else
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, pi);
}
一些耗时操作(网络IO、文件IO、CPU/GPU密集型任务)会阻塞线程直到操作完成,
Kotlin
的协程提供一种避免阻塞且更廉价可控的操作: 协程挂起(coroutine suspension), 协程将复杂异步操作放入底层库中,程序逻辑可顺序表达,以此简化异步编程, 该底层库将用户代码包装为回调/订阅事件,在不同线程(甚至不同机器)调度执行!
Kotlin
的协程还能实现其它语言的异步机制(asynchronous mechanisms
),
例如源于C#和ECMAScript(js)的async/await
机制,
源于Go的channel/select
机制,源于C#和Python的generators/yield
机制。
协程是通过编译技术实现(不需要虚拟机VM/操作系统OS的支持),通过插入相关代码来生效! 与之相反,线程/进程是需要虚拟机VM/操作系统OS的支持,通过调度CPU执行生效!
线程阻塞的代价昂贵, 尤其在高负载时的可用线程很少,阻塞线程会导致一些重要任务缺少可用线程而被延迟!
协程挂起几乎无代价,无需上下文切换或涉及OS, 最重要的是,协程挂起可由用户控制:可决定挂起时发生什么,并根据需求优化/记录日志/拦截!
另一个不同之处是,协程不能在随机指令中挂起,只能在挂起点挂起(调用标记函数)!
当调用[suspend修饰的函数]时会发生协程挂起:
suspend fun doSomething(foo: Foo): Bar {
}
该函数称为挂起函数,调用它们可能挂起协程(如果调用结果已经可用,协程库可决定不挂起) 挂起函数能像普通函数获取参数和返回值,但只能在协程/挂起函数中被调用!
启动协程,至少要有一个挂起函数,通常是匿名的(即挂起lambda表达式),一个简化的async函数(源自kotlinx.coroutines库):
//async函数是一个普通函数(不是挂起函数)
//block参数有suspend修饰,是一个匿名的挂起函数(即挂起lambda表达式)
fun <T> async(block: suspend () -> T)
async {
//doSomething在挂起函数(挂起lambda)中被调用
doSomething(foo)
...
}
async {
...
//await()是挂起函数,该函数挂起一个协程,直到执行完成返回结果
val result = computation.await()
挂起函数不能在普通函数中被调用:
fun main(args: Array<String>) {
doSomething() //错误: 挂起函数不能在非协程中被调用
}
挂起函数可以是虚拟的,当覆盖它们时,必须指定suspend修饰符:
interface Base {
suspend fun foo()
}
class Derived: Base {
override suspend fun foo() {
}
}
粗略地认识协程机制原理是相当重要的!
协程是通过编译技术实现(不需要虚拟机VM/操作系统OS的支持),通过插入相关代码来生效! 与之相反,线程/进程是需要虚拟机VM/操作系统OS的支持,通过调度CPU执行生效!
基本上,每个挂起函数都转换为状态机,对应于挂起调用; 在挂起协程前,下一状态和相关局部变量等被存储在编译器生成的类字段中; 在恢复协程时,状态机从下一状态进行并恢复局部变量!
一个挂起的协程可作为保存挂起状态和局部变量的对象,对象类型是Continuation, 在底层,挂起函数有一个Continuation类型的额外参数
关于协程工作原理的更多细节可查看: https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md
阶段性总结有利于精确自己的目标, 以及为后续的想法开辟空间.
因此开始有必要整理记录.
但是因为没必要像写paper那样规范使用latex, 因此就选择了Markdown.
Windows - MarkdownPad
Github Pages - (If you have one)
[TOC]
由于github不支持显示TOC, 因此需要先用markdown-toc4进行预处理 也可以使用sublime里的markdown-toc5插件.
# content
## content
### content
......
一共可以设置六级标题
* 1
* 2
* 3 * 1 * 2 * 3
1. 1
2. 2
3. 3 1. 1 2. 2 3. 3
- AAA
+ A
- a
1. contentA
2. contentB
> contentA
>> contentB
contentA
contentB
之后的文本内容需要插入空行
![icon](link to the picture)
[content](link to the content)
[content][1]
[1]:Url [content][1] [1]:Url
<url>
***
---
| Tables | Are | Cool |
| ------------- |:-------------:| -----:|
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
Tables | Are | Cool |
---|---|---|
col 3 is | right-aligned | $1600 |
col 2 is | centered | $12 |
zebra stripes | are neat | $1 |
``` [python]
@requires_authorization
def add(a, b): # add a and b
return a+b
class TA:
```
@requires_authorization
def add(a, b): # add a and b
return a+b
class TA:
or 每行文字前加4个空格或者1个Tab
**content** **content**
__content__ __content__
*content* *content*
_content_ _content_
<font face="黑体">我是黑体字</font>
<font face="微软雅黑">我是微软雅黑</font>
<font face="Verdana">I like Verdana format</font>
git 帮助我们进行代码的版本控制,我于2015/10/1花费一天时间学习一个关于git的视频,然后再参考几篇博客,将git的使用方法全部弄清楚。let's begin!
参考官网的安装方法 —— [git web]
working -add file- staging index -commit- repositiry
git checkout [commit hash] – file
usage : git reset –soft [commit hash] git reset HEAD file -n try to do -f force to do
.gitignore
it can help us to ignore some file or dir reference :
- git branch
- create -> git branch new_branch_name
- switch -> git checkout branch_name
- git checkout -b new_branch_name
- git diff [branch1]..[branch2] (use –color-words)
- git branch –merged
- git branch -m old_name new_name (–move)
- git barnch -d(–delete) name (-D to delete a non-empty branch)
- prompt
- export PS1=’$(__git_ps1 “(%s)”) > ‘
- export PS1=’\W$(__git_ps1 “(%s)”) > ‘
- export PS1=$PS1’$(__git_ps1 “(%s)”) > ‘ (it’s cool !)
Attantion: barnch is a stack mode, current branch can’t be delete
- git merge exist_branch
- git branch –merged
- conflict
- change by yourselt
- git log –graph –oneline –all –decorate
- git mergetool –tool=
Attention:
Easily, this can be changed to
echo # >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/[User account]/[project name].git
git push -u origin master
[远程分支的使用] git checkout -b [new_branch] (make some change) git commit -am “word” git push [远程仓库名] [远程分支名(new_branch)]
password caching
Password Caching or save the ssh key.