被問到啊哈哈哈,宛如一個(gè)智障的我為什么沒有想到在验!
性能優(yōu)化肯定會省電啊啊啊
其他的沒說,這個(gè)怎么……
憋說了堵未,來來來腋舌,整理一波
轉(zhuǎn)載自享受技術(shù)帶來的快樂
(一)性能優(yōu)化
Android開發(fā)除了NDK之外,使用的都是Java語言渗蟹,而Java語言是一種基于虛擬機(jī)JVM運(yùn)行的語言块饺,所以相比C/C++語言來說,效率是比較低的雌芽。Java需要占用大量內(nèi)存來換取執(zhí)行速度授艰,而不定期的GC機(jī)制,直接導(dǎo)致Android界面的卡頓現(xiàn)象世落。
Java語言優(yōu)化
1. 使用非阻塞I/O
版本較低的JDK不支持非阻塞I/O API淮腾。為了避免I/O阻塞,一些應(yīng)用采用了創(chuàng)建大量線程的方法(在較好的情況下屉佳,會使用一個(gè)緩沖池)谷朝。這種技術(shù)可以在許多必須支持并發(fā)I/O流的應(yīng)用中見到,如web服務(wù)器等武花。然而圆凰,創(chuàng)建Java線程需要相當(dāng)可觀的開銷。Java在JDK 1.4及以后版本中提供了一套API來專門操作非阻塞I/O体箕,我們可以再java.nio包及其子包中找到相關(guān)的類和接口专钉。由于這套API是JDK新提供的I/O API,因此累铅,也叫New I/O跃须,這就是包名nio的由來。這套API由3個(gè)主要的部分組成:緩沖區(qū)(Buffers)娃兽、通道(Channels)和非阻塞I/O的核心類回怜。
2. 慎用異常
異常對性能不利。拋出異常首先要?jiǎng)?chuàng)建一個(gè)新的對象换薄。 Throwable 接口的構(gòu)造函數(shù)調(diào)用名為 fillnStackTrace()的本地(Native)方法玉雾,fillnStackTrace() 方法檢查堆棧,收集調(diào)用跟蹤信息轻要。只要有異常被拋出复旬,VM就必須調(diào)整調(diào)用堆棧,因?yàn)樵谔幚磉^程中創(chuàng)建了一個(gè)新的對象冲泥。異常只能用于錯(cuò)誤處理驹碍,不應(yīng)該用來控制程序流程壁涎。
3. 變量和修飾符
不要重復(fù)初始化變量。默認(rèn)情況下志秃,調(diào)用類的構(gòu)造函數(shù)時(shí)怔球,Java會把變量初始化成確定的值:所有的對象被設(shè)置成null,整數(shù)變量(byte浮还、short竟坛、int、long)設(shè)置成0钧舌,float和double設(shè)置成0.0担汤,邏輯值設(shè)置成false。所有盡量不要重復(fù)初始化變量洼冻。
盡量使用局部變量崭歧,調(diào)用方法時(shí)傳遞的參數(shù)以及在調(diào)用中創(chuàng)建的臨時(shí)變量都保存在棧(stack)中,速度較快撞牢,并且隨所在線程的死亡而自動(dòng)銷毀率碾。其他變量,如靜態(tài)變量屋彪、實(shí)例變量等所宰,都在堆(heap)中創(chuàng)建,速度較慢撼班,垃圾回收是的耗能會導(dǎo)致APP出現(xiàn)卡頓現(xiàn)象歧匈。
盡量指定類的final修飾符垒酬。帶有final修飾符的類是不可派生的砰嘁。另外,如果指定一個(gè)類為final勘究,則該類所有的方法都是final矮湘。Java編譯器會尋找機(jī)會內(nèi)聯(lián)(inline)所有的final方法。此舉能夠使性能平均提高50%口糕。
私有內(nèi)部類要訪問外部類的field或方法時(shí)缅阳,其成員變量不要用private,因?yàn)樵诰幾g時(shí)會生成setter/getter影響性能景描∈欤可以把外部類的field或者方法聲明為包訪問權(quán)限。
如果方法用不到成員變量超棺,可以把方法申明為static向族,性能會提高到15%到20%。
4. 其他方面:
- 用位操作代替乘除法棠绘;
- 用StringBuilder代替拼接操作件相;
- 對算法進(jìn)行復(fù)雜度的改進(jìn)(必要的時(shí)候可以空間換時(shí)間)再扭;
- 合理利用浮點(diǎn)數(shù),浮點(diǎn)數(shù)比整形慢兩倍夜矗。
- 網(wǎng)絡(luò)優(yōu)化泛范、異步線程、圖片使用緩存等紊撕。
UI布局優(yōu)化
1.布局層數(shù)盡量少罢荡,RelativeLayout來代替LinearLayout,因?yàn)镽elativeLayout性能更優(yōu)逛揩,且可以簡單實(shí)現(xiàn)LinearLayout嵌套才能實(shí)現(xiàn)的布局柠傍。
2.采用<merge>標(biāo)簽優(yōu)化合并布局層數(shù):系統(tǒng)在編譯XML布局文件時(shí)不會為<merge>生成任何節(jié)點(diǎn),通過合并可以大大減少標(biāo)簽的生成辩稽。
3.采用<include>標(biāo)簽共享重用其他布局:并用android:id屬性覆蓋被引用布局文件中頂層節(jié)點(diǎn)的android:id屬性值惧笛。
<!—引用mylayout.xml文件>
<include android:id=”@+id/layout1” layout=”@layout/mylayout”/>
- <viewstub> 標(biāo)簽:viewstub標(biāo)簽同include標(biāo)簽一樣可以用來引入一個(gè)外部布局,不同的是逞泄,viewstub引入的布局默認(rèn)不會擴(kuò)張患整,即既不會占用顯示也不會占用位置,從而在解析layout時(shí)節(jié)省cpu和內(nèi)存喷众。 <viewstub> 常用來引入那些默認(rèn)不會顯示各谚,只在特殊情況下顯示的布局,如進(jìn)度布局到千、網(wǎng)絡(luò)失敗顯示的刷新布局昌渤、信息出錯(cuò)出現(xiàn)的提示布局等。
5.通過Android SDK中tools目錄下的 layoutopt 命令查看你的布局是否需要優(yōu)化憔四。
6.將Activity中的window的背景圖設(shè)置為空膀息。 .getWindow().setBackgroundDrawable(null) ;android默認(rèn)的背景不為空了赵。
7.View中設(shè)置緩存屬性 lsetDrawingCache l為true潜支。動(dòng)態(tài)加載View時(shí)采用ViewStub避免一些不經(jīng)常的視圖長期握住引用。
8.采用SurfaceView在子線程刷新UI柿汛,避免手勢的處理和繪制在同一UI線程(普通View都這樣做)冗酿。
-
9.ListView的優(yōu)化
- item盡可能的減少使用的控件和布局的層次;
- RelativeLayout是絕對的利器络断,通過它可以減少布局的層次裁替。
- 盡可能的復(fù)用控件,這樣可以減少 ListView的內(nèi)存使用貌笨,減少滑動(dòng)時(shí)GC次數(shù)弱判。
- ListView的背景色與cacheColorHint設(shè)置相同顏色,可以提高滑動(dòng)時(shí)的渲染性能躁绸。
- ListView中g(shù)etView是性能是關(guān)鍵裕循,這里要盡可能的優(yōu)化臣嚣。
- getView方法中要重用view;
- getView方法中不能做復(fù)雜的邏輯計(jì)算剥哑, 特別是數(shù)據(jù)庫操作硅则,否則會嚴(yán)重影響滑動(dòng)時(shí)的性能。
數(shù)據(jù)庫優(yōu)化
有些能用文件操作的株婴,盡量使用文件操作怎虫,文件操作的速度比數(shù)據(jù)庫的操作要快10倍左右。
Cursor的使用困介,管理好cursor大审,不要每次打開關(guān)閉cursor,因?yàn)榇蜷_關(guān)閉cursor非常耗時(shí)座哩。Cursor.require用于刷cursor徒扶。同時(shí)由于SQLiteDatabase對象較為耗費(fèi)資源,所以我們在使用完SQLiteDatabase對象之后根穷,必須立即關(guān)閉它姜骡,避免它繼續(xù)占用資源,否則我們繼續(xù)程序可能會導(dǎo)致OOM或者其他異常屿良。
SQLite使用事務(wù),也可以自定義事務(wù)圈澈。使用事務(wù)好處是原子提交和更優(yōu)性能。
Db.beginTransaction();
Db.setTransactionSuccessful();
Db.end Transaction();
可以建立索引尘惧,增加檢索的速度康栈。(當(dāng)某字段數(shù)據(jù)更新頻率較低,查詢頻率較高喷橙,經(jīng)常有范圍查詢(>,<, =, >=, <=)或orderby啥么、group by發(fā)生時(shí)建議使用索引; 經(jīng)常同時(shí)存取多列重慢,且每列都含有重復(fù)值可考慮建立復(fù)合索引)饥臂。
批量插入逊躁、更新使用原子操作似踱,采用事務(wù)等方式。
查詢時(shí)返回更少的結(jié)果集及更少的字段稽煤。
少用cursor.getColumnIndex(可以在建表的時(shí)候用static變量記住某列的index核芽,直接調(diào)用相應(yīng)index而不是每次查詢。)
優(yōu)化sql語句字符串等酵熙,語句的拼接使用StringBuilder代替String轧简。
新機(jī)制或者借用工具
- 采用JNI技術(shù),將耗時(shí)間的處理放到c/c++層處理匾二。適當(dāng)?shù)牟捎肗DK編程可以提高效率哮独,但是內(nèi)存回收不穩(wěn)定拳芙,所以說適當(dāng)。
懶加載和緩存機(jī)制:訪問網(wǎng)絡(luò)的耗時(shí)操作啟動(dòng)一個(gè)新線程來做皮璧,而不要在UI線程做舟扎。還有從網(wǎng)絡(luò)上獲取大量圖片的時(shí)候,可以本地緩存悴务,下次獲取同樣圖片的時(shí)候睹限,可以先從本地獲取,本地?zé)o再從網(wǎng)絡(luò)獲取讯檐。
通過Android SDK中tools目錄下的layoutopt命令查看你的布局是否需要優(yōu)化羡疗;hierarchy viewer可以方便的查看Activity的布局,各個(gè)View的屬性别洪、measure叨恨、layout、draw的時(shí)間挖垛,如果耗時(shí)較多會用紅色標(biāo)記特碳,否則顯示綠色;利用android自帶的性能跟蹤工具TraceView查看跟蹤函數(shù)調(diào)用晕换,跟蹤方法跟蹤各部分的執(zhí)行效率午乓。
可以在方法執(zhí)行前后各使用system.currentTimeMillis方法獲取當(dāng)前系統(tǒng)的時(shí)間(毫秒),兩個(gè)時(shí)間之差可以計(jì)算出方法的執(zhí)行時(shí)間闸准,進(jìn)而可以改進(jìn)優(yōu)化益愈。
獲取系統(tǒng)的內(nèi)存信息
//獲取系統(tǒng)內(nèi)存總數(shù)
Long total = Runtime.getRuntime().totalMemory();
//獲取剩余內(nèi)存
Long free = Runtime.getRuntime().freeMemory();
//獲取已經(jīng)使用內(nèi)存
Long used = total – free;
(二)Android省電開發(fā)之CPU降頻
轉(zhuǎn)載自Matrixxu博客專欄
在Android系統(tǒng)的耗電量排行里,cpu的耗電占了比較大的一部分比例夷家,也就是說蒸其,cpu的使用率和使用頻率將直接或間接的影響電量的分配和使用,但很遺憾库快,android-sdk中沒有為android的開發(fā)者提供類似cpu管理的功能摸袁,但是當(dāng)下很多省電類應(yīng)用或?qū)I(yè)的cpu管理軟件都提供了cpu的降頻甚至是超頻的功能,那么這樣的功能是如何實(shí)現(xiàn)的义屏,本文將詳細(xì)說明在android環(huán)境下調(diào)整cpu頻率的一些方法靠汁,僅供參考。
- CPU的工作頻率
單位赫茲或者兆赫茲闽铐。CPU的工作頻率越高蝶怔,耗電量越大,反之亦然兄墅。
- CPU的調(diào)控模式
英文詞為:Governor踢星,解釋為調(diào)速器,控制器隙咸。android的framework是基于Linux平臺的沐悦,那么cpu的管理體系這塊也跟linux基本上一樣成洗,其中包括cat命令,和一些文件的讀寫配置都是基本上差不多的藏否。Linux在管理CPU方面泌枪,提供了如下幾種調(diào)控模式,分別為:
調(diào)控模式 | 效果 |
---|---|
performance | 將CPU的工作頻率調(diào)整到最大模式秕岛,讓CPU充分工作 |
powersave | 將cpu的工作頻率調(diào)整到節(jié)能模式碌燕,這個(gè)模式下的CPU頻率最低 |
ondemand | 定期檢查負(fù)載。當(dāng)負(fù)荷超越了閾值,設(shè)置的CPU運(yùn)行以最高的頻率继薛。當(dāng)負(fù)載低于相同的閾值,設(shè)置的CPU運(yùn)行在下一個(gè)的最低頻率修壕。導(dǎo)致更少的延遲比。ondemand從字面翻譯是“根據(jù)需求遏考,按照需要”慈鸠,cpu在工作的時(shí)候頻率會在一個(gè)最大值和最小值之間波動(dòng),當(dāng)負(fù)載提高時(shí)灌具,該調(diào)控期會自動(dòng)提高cpu的頻率青团,反之亦然】ч梗“Causes less latency than the conservative governor.”這句話的意思是督笆,該模式跟conservative相比,會導(dǎo)致更少的延遲诱贿。ok娃肿,那讓我們再看看conservative是如何解釋的。 |
conservative | 該模式與ondemand的最大區(qū)別在于:conservative模式不會立刻在負(fù)載增加的情況下將cpu頻率調(diào)整到最大珠十,會調(diào)整到比目前頻率稍微大的頻段去工作料扰。所以在某種極端情況下,該模式的延遲會大于ondemand焙蹭。 |
usersapce | 將cpu的掌控權(quán)交給了用戶態(tài)晒杈,也就是交給了應(yīng)用程序,應(yīng)用程序可以通過配置文件的方式修改cpu的頻率信息孔厉。 |
public class CPUFreqSetting {
/**
* cpu cat命令大全
* cat [%cpuFreqPath%]/cpuinfo_cur_freq (當(dāng)前cpu頻率)
* cat [%cpuFreqPath%]/cpuinfo_max_freq (最大cpu頻率)
* cat [%cpuFreqPath%]/cpuinfo_min_freq (最小cpu頻率)
* cat [%cpuFreqPath%]/related_cpus (cpu數(shù)量標(biāo)號,從0開始,如果是雙核,結(jié)果為0,1)
* cat [%cpuFreqPath%]/scaling_available_frequencies (cpu所有可用頻率)
* cat [%cpuFreqPath%]/scaling_available_governors (cpu所有可用調(diào)控模式)
* cat [%cpuFreqPath%]/scaling_available_governors (cpu所有可用調(diào)控模式)
* cat [%cpuFreqPath%]/scaling_cur_freq (?????)
* cat [%cpuFreqPath%]/scaling_driver (?????)
* cat [%cpuFreqPath%]/scaling_governor (?????)
* cat [%cpuFreqPath%]/scaling_max_freq (?????)
* cat [%cpuFreqPath%]/scaling_min_freq (?????)
* cat [%cpuFreqPath%]/scaling_setspeed (?????)
* cat [%cpuFreqPath%]/cpuinfo_transition_latency (?????)
*/
private final String TAG = "SetCPU";
private final String cpuFreqPath = "/sys/devices/system/cpu/cpu0/cpufreq";
private final static String PERFORMANCE_GOVERNOR = "performance";
private final static String POWER_SAVE_GOVERNOR = "performance";
private final static String ONDEMAND_GOVERNOR = "performance";
private final static String CONSERVATIVE_GOVERNOR = "performance";
private final static String USERSAPCE_GOVERNOR = "performance";
// public void powerSaveGovernor() {
// List<String> governors = readCpuGovernors();
// if (governors.contains(object)) {
//
// }
// }
/**
* 獲得當(dāng)前CPU調(diào)控模式
*/
public void getCpuCurGovernor() {
try {
DataInputStream is = null;
Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_governor");
is = new DataInputStream(process.getInputStream());
String line = is.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 重寫CPU調(diào)控模式
* @param governor
* @return
*/
private boolean writeCpuGovernor(String governor) {
DataOutputStream os = null;
byte[] buffer = new byte[256];
String command = "echo " + governor + " > " + cpuFreqPath + "/scaling_governor";
Log.i(TAG, "command: " + command);
try {
Process process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
Log.i(TAG, "exit value = " + process.exitValue());
} catch (IOException e) {
Log.i(TAG, "writeCpuGovernor: write CPU Governor(" + governor + ") failed!");
return false;
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
/**
* 獲得CPU所有調(diào)控模式
* @return
*/
private List<String> readCpuGovernors() {
List<String> governors = new ArrayList<String>();
DataInputStream is = null;
try {
Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_available_governors");
is = new DataInputStream(process.getInputStream());
String line = is.readLine();
String[] strs = line.split(" ");
for (int i = 0; i < strs.length; i++)
governors.add(strs[i]);
} catch (IOException e) {
Log.i(TAG, "readCpuGovernors: read CPU Governors failed!");
}
return governors;
}
}
(三)Android省電開發(fā)之service
Android應(yīng)用開發(fā)中拯钻,難免會遇到service開發(fā)。android中服務(wù)是運(yùn)行在后臺的東西烟馅,級別與activity差不多说庭。既然說service是運(yùn)行在后臺的服務(wù)然磷,那么它就是不可見的郑趁,沒有界面的東西。Service和其他組件一樣姿搜,都是運(yùn)行在主線程中寡润,因此不能用它來做耗時(shí)的請求或者動(dòng)作捆憎。你可以在服務(wù)中開一個(gè)線程,在線程中做耗時(shí)動(dòng)作梭纹。
** 我們從三個(gè)方面來淺析一下service的省電開發(fā)**
** 查看service是否存活以及降低優(yōu)先級:**
假如一個(gè)service工作完成躲惰,但是來不及關(guān)掉或者kill掉,用戶又看不見变抽,所以這個(gè)service將會一直在后臺運(yùn)行础拨,勢必耗電。所以我們可以降低某些不常用service進(jìn)程的優(yōu)先級绍载,在系統(tǒng)內(nèi)存吃緊的情況下诡宗, 進(jìn)程優(yōu)先級低的service容易被系統(tǒng)kill掉。除此之外击儡,可以利用監(jiān)聽系統(tǒng)廣播來判斷service狀態(tài)是否存活塔沃,死亡即可手動(dòng)kill掉。** 用IntentService代替Service開發(fā):**
普通服務(wù)一旦啟動(dòng)之后阳谍,就會一直處于運(yùn)行狀態(tài)蛀柴,必須調(diào)用stopService()或者stopSelf()方法才能讓服務(wù)停止下來。為了簡單的創(chuàng)建一個(gè)異步的矫夯、會自動(dòng)挺值得服務(wù)鸽疾,Android專門提供了一個(gè)IntentService類。IntentService在運(yùn)行完畢后自動(dòng)停止训貌,減少耗電量肮韧。** 后臺執(zhí)行的定時(shí)任務(wù)Alarm機(jī)制:**
Service沒必要一直在后臺運(yùn)行,這時(shí)候的定時(shí)任務(wù)顯得很重要旺订。
Android的定時(shí)任務(wù)有兩種實(shí)現(xiàn)方式弄企,Timer類和Alarm機(jī)制。
- Timer有一個(gè)明顯的短板区拳,不適合長期后臺運(yùn)行的定時(shí)任務(wù)拘领。為了能讓電池更加耐用,每種手機(jī)都會有自己的休眠策略樱调,Android手機(jī)就會在長時(shí)間不操作的情況下自動(dòng)讓CPU進(jìn)入到睡眠狀態(tài)约素,這就有可能導(dǎo)致Timer中的定時(shí)任務(wù)無法正常運(yùn)行。
- Alarm機(jī)制則不存在這種情況笆凌,它具有喚醒CPU的功能圣猎,即可以保證每次需要執(zhí)行定時(shí)任務(wù)的時(shí)候CPU能正常工作。
? PS:Alarm機(jī)制
從Android 4.4之后乞而,Alarm任務(wù)的觸發(fā)時(shí)間將會變得不準(zhǔn)確送悔,有可能會延遲一段時(shí)間后任務(wù)才能得到執(zhí)行。這不是bug,而是系統(tǒng)在耗電性方面進(jìn)行的優(yōu)化欠啤。系統(tǒng)會自動(dòng)檢測目前有多少Alarm任務(wù)存在荚藻,然后將觸發(fā)時(shí)間將近的幾個(gè)任務(wù)放在一起執(zhí)行,這就可以大幅度的減少CPU被喚醒的次數(shù)洁段,從而有效延長電池的使用時(shí)間应狱。
但是,Android提供了解決方案祠丝,使用AlarmManager的 setExact() 來代替 set() 方法疾呻,基本可以保證任務(wù)準(zhǔn)時(shí)執(zhí)行。
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread() {
@Override
public void run() {
//耗時(shí)操作
}
}.run();
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long triggerAtTime = SystemClock.elapsedRealtime() + 10 * 1000;
Intent intent = new Intent(this, MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);
return super.onStartCommand(intent, flags, startId);
}
}
// 讓定時(shí)任務(wù)的觸發(fā)時(shí)間從系統(tǒng)開機(jī)算起写半,不會喚醒CPU
AlarmManager.ELAPSED_REALTIME;
//讓定時(shí)任務(wù)的觸發(fā)時(shí)間從系統(tǒng)開機(jī)算起罐韩,會喚醒CPU
AlarmManager.ELAPSED_REALTIME_WAKEUP;
// 讓定時(shí)任務(wù)的觸發(fā)時(shí)間從1970年1月1日0點(diǎn)算起,不會喚醒CPU
AlarmManager.RTC;
// 讓定時(shí)任務(wù)的觸發(fā)時(shí)間從1970年1月1日0點(diǎn)算起污朽,會喚醒CPU
AlarmManager.RTC_WAKEUP;
// 獲取系統(tǒng)開機(jī)至今所經(jīng)歷時(shí)間的毫秒數(shù)
SystemClock.elapsedRealtime();
// 獲取從1970年1月1日0點(diǎn)至今所經(jīng)歷時(shí)間的毫秒數(shù)
SystemClock.currentThreadTimeMillis();
(四)Android省電開發(fā)之網(wǎng)絡(luò)
除了常規(guī)的異步網(wǎng)絡(luò)散吵、多線程技術(shù)、本地緩存等等之外蟆肆,Android省電開發(fā)還有一個(gè)重要的方面是: WIFI 比蜂窩數(shù)據(jù)更省電:
- a)盡量在Wi-Fi下傳輸數(shù)據(jù)矾睦,當(dāng)然這是廢話,不過可以考慮在有Wi-Fi的時(shí)候做預(yù)加載炎功,比如應(yīng)用中心的zip包枚冗、手Q web類應(yīng)用的離線資源等;
- b)非Wi-Fi下,盡量減少網(wǎng)絡(luò)訪問蛇损,每一次后臺交互都要考慮是否必須赁温。雖然WiFi接入方式已經(jīng)占到移動(dòng)互聯(lián)網(wǎng)用戶的50%,但是是有些手機(jī)設(shè)置為待機(jī)關(guān)閉WiFi連接淤齐,即便有Wi-Fi信號也只能切換到蜂窩數(shù)據(jù);
一篇博文中的數(shù)據(jù)測試
滅屏情況:滅屏傳輸填具,高負(fù)載download的時(shí)候WiFi最省電(70mA)碘裕,3G(270mA)和2G(280mA)相當(dāng)括尸,是WiFi的4倍左右;
亮屏情況:亮屏傳輸镀钓,高負(fù)載download的時(shí)候WiFi最省電(280mA),3G(360mA)和2G(370mA)相當(dāng)祭务,是WiFi的1.3倍左右;
所以在Android應(yīng)用省電開發(fā)中内狗,我們可以在獲取網(wǎng)絡(luò)方式的方面加以考慮。
(五)Android省電開發(fā)之Android L5.0(ART)登場
-
1. 默認(rèn)的ART運(yùn)行模式
安卓4.4系統(tǒng)中引入了全新的ART模式嗎义锥,相比之前流行已久的Dalvik模式有了很大的改變柳沙。
在Dalvik中,應(yīng)用每次運(yùn)行拌倍,字節(jié)碼都需要通過即時(shí)編譯器轉(zhuǎn)換為機(jī)器碼赂鲤,這回拖慢應(yīng)用的運(yùn)行效率噪径,而在ART環(huán)境中,應(yīng)用在第一次安裝時(shí)蛤袒,字節(jié)碼就會預(yù)先編譯成機(jī)器碼熄云,使其成為了真正的本地應(yīng)用膨更。這個(gè)過程叫做預(yù)編譯妙真。這樣的話,應(yīng)用的啟動(dòng)和執(zhí)行都會變得更加快速荚守。但是ART的缺點(diǎn)是預(yù)編譯完的機(jī)器人占用了更大的存儲空間珍德,應(yīng)用的安裝需要更長的時(shí)間。但是犧牲空間時(shí)間換取省電速度矗漾,在Android應(yīng)用中還是可以接受的锈候,畢竟性能的提升,運(yùn)行速度的變快敞贡,體驗(yàn)更流暢泵琳,電池續(xù)航更久顯得更重要。
- 2.利用JobScheduler API
過去誊役,如果開發(fā)人員想通過后臺調(diào)取服務(wù)器數(shù)據(jù)获列,或完成某些處理工作,應(yīng)用程序必須先監(jiān)聽是否有事件正在發(fā)生蛔垢,并為自己設(shè)定一個(gè)喚醒時(shí)間击孩,一旦應(yīng)用程序開始運(yùn)行,他需要檢查各種環(huán)境條件鹏漆,以確定是否具備條件讓它完成工作巩梢,還是需要稍后再試,這種方式不僅復(fù)雜艺玲,而且容易出錯(cuò)括蝠,它會不斷的浪費(fèi)資源,比如當(dāng) 一個(gè)應(yīng)用程序被喚醒后饭聚,發(fā)現(xiàn)條件不符合就只能去睡覺并為下次喚醒再次設(shè)定時(shí)間又跛,這是一個(gè)反復(fù)的過程。
這個(gè)問題若治,將引用 JobScheduler 來修復(fù)慨蓝,它作為一個(gè)調(diào)度應(yīng)用程序,負(fù)責(zé)當(dāng)應(yīng)用程序被喚醒時(shí)端幼,提供適當(dāng)?shù)倪\(yùn)行環(huán)境礼烈,所以開發(fā)者不用再讓程序檢測環(huán)境是否符合需求,開發(fā)人員只需要按照標(biāo)準(zhǔn)的流程來婆跑,調(diào)度程序會自動(dòng)為喚醒的程序此熬,準(zhǔn)備好運(yùn)行環(huán)境。應(yīng)用程序可以使用這個(gè)調(diào)度程序,來喚醒他們犀忱,比如當(dāng)設(shè)備連接到充電器后募谎,調(diào)度程序?qū)拘涯切┬枰幚砥鞴ぷ鞯某绦颍屗麄冞M(jìn)行工作阴汇,或者在設(shè)備連接至WiFi網(wǎng)絡(luò)的時(shí)候上傳下載照片数冬,更新內(nèi)容等。該調(diào)度程序還支持一個(gè)時(shí)間窗口搀庶,以便它可以喚醒一組應(yīng)用程序拐纱,這將使那些不需要精確喚醒時(shí)間,但每隔一兩小時(shí)需要運(yùn)行一次的程序能在同一時(shí)間點(diǎn)運(yùn)行哥倔,這樣就能讓處理器保持更長時(shí)間的休眠秸架。
JobScheduler 的優(yōu)勢相當(dāng)巨大,它不僅可以幫助手機(jī)節(jié)省電量咆蒿, 實(shí)際由于不在需要監(jiān)聽东抹,更改和設(shè)置報(bào)警,還可以幫助開發(fā)人員減少代碼書寫量沃测。目前該JobScheduler類缭黔,已經(jīng)加入Android L開發(fā)者預(yù)覽版。
-
3.各種省電新模式和新技術(shù)
(1) 全新的Material Design風(fēng)格用戶界面
新的用戶界面更加簡潔芽突、色彩更加豐富试浙。動(dòng)畫效果更加合理生動(dòng),同時(shí)加入實(shí)時(shí)陰影的3D視圖寞蚌,更多的使用卡片風(fēng)格的顯示效果田巴。全平臺風(fēng)格也變得更為統(tǒng)一。(2) 新的通知消息系統(tǒng)
允許用戶管理通知中心中的通知消息挟秤。原先的Android通知欄幾乎是處于無法控制的狀態(tài)壹哺,所有的應(yīng)用通知都會彈出,要想關(guān)閉只能進(jìn)到每一個(gè)應(yīng)用中去單獨(dú)設(shè)置艘刚,或是使用第三方軟件來實(shí)現(xiàn)統(tǒng)一管理管宵。但是現(xiàn)在不用了,Android 5.0已經(jīng)自帶了通知管理界面攀甚。(3) 多任務(wù)界面有著全新的Google Now卡片風(fēng)格
通知中心融入更多的卡片式風(fēng)格箩朴,即使是在鎖屏狀態(tài)下也可以進(jìn)行多種功能操作。同時(shí)用戶可以自定義通知的優(yōu)先級別秋度,使得用戶不會錯(cuò)過任何重要的通知炸庞。還可以設(shè)置特定的通知權(quán)限,只有被允許的通知消息才會推送荚斯。同時(shí)還具有操作性埠居,比如用戶在游戲時(shí)有電話打入查牌,不會以全屏顯示,而是彈出可操作的通知卡片滥壕,用戶可選擇接聽或拒接纸颜,不影響游戲繼續(xù)進(jìn)行。(4) Project Volta省電模式绎橘、BatterySaver省電模式
Android 5.0的省電模式是通過 JobSchedulerAPI 以及自動(dòng)調(diào)節(jié)屏幕亮度胁孙、刷新率來達(dá)到省電的效果,而且還使用了Project Volta量化每個(gè)應(yīng)用的耗電量金踪,在手機(jī)快沒電的情況下主動(dòng)降低CPU的主頻或者關(guān)閉通訊模塊浊洞,以獲得更長的待機(jī)時(shí)間牵敷。還配備了一個(gè) Battery Bistorian 電池歷史記錄功能胡岔,可讓詳細(xì)顯示設(shè)備的耗電情況。
以上整理自網(wǎng)絡(luò)~
如有錯(cuò)誤還請大家多多指教啊哈哈