




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android性能優(yōu)化電量的方法是什么
本文在下為大家詳細(xì)介紹“Android性能優(yōu)化電量的方法是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Android性能優(yōu)化電量的方法是什么”文章能幫助大家解決疑惑,下面跟著在下的思路慢慢深入,一起來學(xué)習(xí)新知識吧。1)UnderstandingBatteryDrain手機(jī)各個硬件模塊的耗電量是不一樣的,有些模塊非常耗電,而有些模塊則相對顯得耗電量小很多。電量消耗的計算與統(tǒng)計是一件麻煩而且矛盾的事情,記錄電量消耗本身也是一個費(fèi)電量的事情。唯一可行的方案是使用第三方監(jiān)測電量的設(shè)備,這樣才能夠獲取到真實(shí)的電量消耗。當(dāng)設(shè)備處于待機(jī)狀態(tài)時消耗的電量是極少的,以N5為例,打開飛行模式,可以待機(jī)接近1個月??墒屈c(diǎn)亮屏幕,硬件各個模塊就需要開始工作,這會需要消耗很多電量。使用WakeLock或者JobScheduler喚醒設(shè)備處理定時的任務(wù)之后,一定要及時讓設(shè)備回到初始狀態(tài)。每次喚醒蜂窩信號進(jìn)行數(shù)據(jù)傳遞,都會消耗很多電量,它比WiFi等操作更加的耗電。2)BatteryHistorianBatteryHistorian是Android5.0開始引入的新API。通過下面的指令,可以得到設(shè)備上的電量消耗信息:$
adb
shell
dumpsys
batterystats
>
xxx.txt
//得到整個設(shè)備的電量消耗信息
$
adb
shell
dumpsys
batterystats
>
>
xxx.txt
//得到指定app相關(guān)的電量消耗信息得到了原始的電量消耗數(shù)據(jù)之后,我們需要通過Google編寫的一個python腳本把數(shù)據(jù)信息轉(zhuǎn)換成可讀性更好的html文件:$
python
historian.py
xxx.txt
>
xxx.html打開這個轉(zhuǎn)換過后的html文件,可以看到類似TraceView生成的列表數(shù)據(jù),這里的數(shù)據(jù)信息量很大,這里就不展開了。3)TrackBatteryStatus&BatteryManager我們可以通過下面的代碼來獲取手機(jī)的當(dāng)前充電狀態(tài)://
It
is
very
easy
to
subscribe
to
changes
to
the
battery
state,
but
you
can
get
the
current
//
state
by
simply
passing
null
in
as
your
receiver.
Nifty,
isn't
that?
IntentFilter
filter
=
new
IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent
batteryStatus
=
this.registerReceiver(null,
filter);
int
chargePlug
=
batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED,
-1);
boolean
acCharge
=
(chargePlug
==
BatteryManager.BATTERY_PLUGGED_AC);
if
(acCharge)
{
Log.v(LOG_TAG,“The
phone
is
charging!”);
}在上面的例子演示了如何立即獲取到手機(jī)的充電狀態(tài),得到充電狀態(tài)信息之后,我們可以有針對性的對部分代碼做優(yōu)化。比如我們可以判斷只有當(dāng)前手機(jī)為AC充電狀態(tài)時才去執(zhí)行一些非常耗電的操作。/**
*
This
method
checks
for
power
by
comparing
the
current
battery
state
against
all
possible
*
plugged
in
states.
In
this
case,
a
device
may
be
considered
plugged
in
either
by
USB,
AC,
or
*
wireless
charge.
(Wireless
charge
was
introduced
in
API
Level
17.)
*/
private
boolean
checkForPower()
{
//
It
is
very
easy
to
subscribe
to
changes
to
the
battery
state,
but
you
can
get
the
current
//
state
by
simply
passing
null
in
as
your
receiver.
Nifty,
isn't
that?
IntentFilter
filter
=
new
IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent
batteryStatus
=
this.registerReceiver(null,
filter);
//
There
are
currently
three
ways
a
device
can
be
plugged
in.
We
should
check
them
all.
int
chargePlug
=
batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED,
-1);
boolean
usbCharge
=
(chargePlug
==
BatteryManager.BATTERY_PLUGGED_USB);
boolean
acCharge
=
(chargePlug
==
BatteryManager.BATTERY_PLUGGED_AC);
boolean
wirelessCharge
=
false;
if
(Build.VERSION.SDK_INT
>=
Build.VERSION_CODES.JELLY_BEAN_MR1)
{
wirelessCharge
=
(chargePlug
==
BatteryManager.BATTERY_PLUGGED_WIRELESS);
}
return
(usbCharge
||
acCharge
||
wirelessCharge);
}4)WakelockandBatteryDrain高效的保留更多的電量與不斷促使用戶使用你的App會消耗電量,這是矛盾的選擇題。不過我們可以使用一些更好的辦法來平衡兩者。假設(shè)你的手機(jī)里面裝了大量的社交類應(yīng)用,即使手機(jī)處于待機(jī)狀態(tài),也會經(jīng)常被這些應(yīng)用喚醒用來檢查同步新的數(shù)據(jù)信息。Android會不斷關(guān)閉各種硬件來延長手機(jī)的待機(jī)時間,首先屏幕會逐漸變暗直至關(guān)閉,然后CPU進(jìn)入睡眠,這一切操作都是為了節(jié)約寶貴的電量資源。但是即使在這種睡眠狀態(tài)下,大多數(shù)應(yīng)用還是會嘗試進(jìn)行工作,他們將不斷的喚醒手機(jī)。一個最簡單的喚醒手機(jī)的方法是使用PowerManager.WakeLock的API來保持CPU工作并防止屏幕變暗關(guān)閉。這使得手機(jī)可以被喚醒,執(zhí)行工作,然后回到睡眠狀態(tài)。知道如何獲取WakeLock是簡單的,可是及時釋放WakeLock也是非常重要的,不恰當(dāng)?shù)氖褂肳akeLock會導(dǎo)致嚴(yán)重錯誤。例如網(wǎng)絡(luò)請求的數(shù)據(jù)返回時間不確定,導(dǎo)致本來只需要10s的事情一直等待了1個小時,這樣會使得電量白白浪費(fèi)了。這也是為何使用帶超時參數(shù)的wakelock.acquice()方法是很關(guān)鍵的。但是僅僅設(shè)置超時并不足夠解決問題,例如設(shè)置多長的超時比較合適?什么時候進(jìn)行重試等等?解決上面的問題,正確的方式可能是使用非精準(zhǔn)定時器。通常情況下,我們會設(shè)定一個時間進(jìn)行某個操作,但是動態(tài)修改這個時間也許會更好。例如,如果有另外一個程序需要比你設(shè)定的時間晚5分鐘喚醒,***能夠等到那個時候,兩個任務(wù)捆綁一起同時進(jìn)行,這就是非精確定時器的核心工作原理。我們可以定制計劃的任務(wù),可是系統(tǒng)如果檢測到一個更好的時間,它可以推遲你的任務(wù),以節(jié)省電量消耗。這正是JobSchedulerAPI所做的事情。它會根據(jù)當(dāng)前的情況與任務(wù),組合出理想的喚醒時間,例如等到正在充電或者連接到WiFi的時候,或者集中任務(wù)一起執(zhí)行。我們可以通過這個API實(shí)現(xiàn)很多免費(fèi)的調(diào)度算法。5)NetworkandBatteryDrain下面內(nèi)容來自官方Training文檔中高效下載章節(jié)關(guān)于手機(jī)(Radio)蜂窩信號對電量消耗的介紹。通常情況下,使用3G移動網(wǎng)絡(luò)傳輸數(shù)據(jù),電量的消耗有三種狀態(tài):Fullpower:能量***的狀態(tài),移動網(wǎng)絡(luò)連接被激活,允許設(shè)備以***的傳輸速率進(jìn)行操作。Lowpower:一種中間狀態(tài),對電量的消耗差不多是Fullpower狀態(tài)下的50%。Standby:***的狀態(tài),沒有數(shù)據(jù)連接需要傳輸,電量消耗最少。下圖是一個典型的3GRadioStateMachine的圖示總之,為了減少電量的消耗,在蜂窩移動網(wǎng)絡(luò)下,***做到批量執(zhí)行網(wǎng)絡(luò)請求,盡量避免頻繁的間隔網(wǎng)絡(luò)請求。通過前面學(xué)習(xí)到的BatteryHistorian我們可以得到設(shè)備的電量消耗數(shù)據(jù),如果數(shù)據(jù)中的移動蜂窩網(wǎng)絡(luò)(MobileRadio)電量消耗呈現(xiàn)下面的情況,間隔很小,又頻繁斷斷續(xù)續(xù)的出現(xiàn),說明電量消耗性能很不好:經(jīng)過優(yōu)化之后,如果呈現(xiàn)下面的圖示,說明電量消耗的性能是良好的:另外WiFi連接下,網(wǎng)絡(luò)傳輸?shù)碾娏肯囊纫苿泳W(wǎng)絡(luò)少很多,應(yīng)該盡量減少移動網(wǎng)絡(luò)下的數(shù)據(jù)傳輸,多在WiFi環(huán)境下傳輸數(shù)據(jù)。那么如何才能夠把任務(wù)緩存起來,做到批量化執(zhí)行呢?下面就輪到JobScheduler出場了。6)UsingJobScheduler使用JobScheduler,應(yīng)用需要做的事情就是判斷哪些任務(wù)是不緊急的,可以交給JobScheduler來處理,JobScheduler集中處理收到的任務(wù),選擇合適的時間,合適的網(wǎng)絡(luò),再一起進(jìn)行執(zhí)行。下面是使用JobScheduler的一段簡要示例,需要先有一個JobService:public
class
MyJobService
extends
JobService
{
private
static
final
String
LOG_TAG
=
"MyJobService";
@Override
public
void
onCreate()
{
super.onCreate();
Log.i(LOG_TAG,
"MyJobService
created");
}
@Override
public
void
onDestroy()
{
super.onDestroy();
Log.i(LOG_TAG,
"MyJobService
destroyed");
}
@Override
public
boolean
onStartJob(JobParameters
params)
{
//
This
is
where
you
would
implement
all
of
the
logic
for
your
job.
Note
that
this
runs
//
on
the
main
thread,
so
you
will
want
to
use
a
separate
thread
for
asynchronous
work
//
(as
we
demonstrate
below
to
establish
a
network
connection).
//
If
you
use
a
separate
thread,
return
true
to
indicate
that
you
need
a
"reschedule"
to
//
return
to
the
job
at
some
point
in
the
future
to
finish
processing
the
work.
Otherwise,
//
return
false
when
finished.
Log.i(LOG_TAG,
"Totally
and
completely
working
on
job
"
+
params.getJobId());
//
First,
check
the
network,
and
then
attempt
to
connect.
if
(isNetworkConnected())
{
new
SimpleDownloadTask()
.execute(params);
return
true;
}
else
{
Log.i(LOG_TAG,
"No
connection
on
job
"
+
params.getJobId()
+
";
sad
face");
}
return
false;
}
@Override
public
boolean
onStopJob(JobParameters
params)
{
//
Called
if
the
job
must
be
stopped
before
jobFinished()
has
been
called.
This
may
//
happen
if
the
requirements
are
no
longer
being
met,
such
as
the
user
no
longer
//
connecting
to
WiFi,
or
the
device
no
longer
being
idle.
Use
this
callback
to
resolve
//
anything
that
may
cause
your
application
to
misbehave
from
the
job
being
halted.
//
Return
true
if
the
job
should
be
rescheduled
based
on
the
retry
criteria
specified
//
when
the
job
was
created
or
return
false
to
drop
the
job.
Regardless
of
the
value
//
returned,
your
job
must
stop
executing.
Log.i(LOG_TAG,
"Whelp,
something
changed,
so
I'm
calling
it
on
job
"
+
params.getJobId());
return
false;
}
/**
*
Determines
if
the
device
is
currently
online.
*/
private
boolean
isNetworkConnected()
{
ConnectivityManager
connectivityManager
=
(ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo
networkInfo
=
connectivityManager.getActiveNetworkInfo();
return
(networkInfo
!=
null
&&
networkInfo.isConnected());
}
/**
*
Uses
AsyncTask
to
create
a
task
away
from
the
main
UI
thread.
This
task
creates
a
*
HTTPUrlConnection,
and
then
downloads
the
contents
of
the
webpage
as
an
InputStream.
*
The
InputStream
is
then
converted
to
a
String,
which
is
logged
by
the
*
onPostExecute()
method.
*/
private
class
SimpleDownloadTask
extends
AsyncTask<JobParameters,
Void,
String>
{
protected
JobParameters
mJobParam;
@Override
protected
String
doInBackground(JobParameters...
params)
{
//
cache
system
provided
job
requirements
mJobParam
=
params[0];
try
{
InputStream
is
=
null;
//
Only
display
the
first
50
characters
of
the
retrieved
web
page
content.
int
len
=
50;
URL
url
=
new
URL("");
HttpURLConnection
conn
=
(HttpURLConnection)
url.openConnection();
conn.setReadTimeout(10000);
//10sec
conn.setConnectTimeout(15000);
//15sec
conn.setRequestMethod("GET");
//Starts
the
query
conn.connect();
int
response
=
conn.getResponseCode();
Log.d(LOG_TAG,
"The
response
is:
"
+
response);
is
=
conn.getInputStream();
//
Convert
the
input
stream
to
a
string
Reader
reader
=
null;
reader
=
new
InputStreamReader(is,
"UTF-8");
char[]
buffer
=
new
char[len];
reader.read(buffer);
return
new
String(buffer);
}
catch
(IOException
e)
{
return
"Unable
to
retrieve
web
page.";
}
}
@Override
protected
void
onPostExecute(String
result)
{
jobFinished(mJobParam,
false);
Log.i(LOG_TAG,
result);
}
}
}然后模擬通過點(diǎn)擊Button觸發(fā)N個任務(wù),交給JobService來處public
class
FreeTheWakelockActivity
extends
ActionBarActivity
{
public
static
final
String
LOG_TAG
=
"FreeTheWakelockActivity";
TextView
mWakeLockMsg;
ComponentName
mServiceComponent;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wakelock);
mWakeLockMsg
=
(TextView)
findViewById(R.id.wakelock_txt);
mServiceComponent
=
new
ComponentName(this,
MyJobService.class);
Intent
startServiceIntent
=
new
Intent(this,
MyJobService.class);
startService(startServiceIntent);
Button
theButtonThatWakelocks
=
(Button)
findViewById(R.id.wakelock_poll);
theButtonThatWakelocks.setText(R.string.poll_server_button);
theButtonThatWakelocks.setOnClickListener(new
View.OnClickListener()
{
@Override
public
void
onClick(View
v)
{
pollServer();
}
});
}
/**
*
This
method
polls
the
server
via
the
JobScheduler
API.
By
scheduling
the
job
with
this
API,
*
your
app
can
be
confident
it
will
execute,
but
without
the
need
for
a
wake
lock.
Rather,
the
*
API
will
take
your
network
jobs
and
execute
them
in
batch
to
best
take
advantage
of
the
*
initial
network
connection
cost.
*
*
The
JobScheduler
API
works
through
a
background
service.
In
this
sample,
we
have
*
a
simple
service
in
MyJobService
to
get
you
started.
The
job
is
scheduled
here
in
*
the
activity,
but
the
job
itself
is
executed
in
MyJ
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025租房合同范本(完美打印版)
- 2025共同租賃商業(yè)物業(yè)合同模板
- 農(nóng)產(chǎn)品倉儲與農(nóng)業(yè)供給側(cè)改革考核試卷
- 《2025勞務(wù)合同聘用離職人員協(xié)議》
- 洗滌機(jī)械的數(shù)字化營銷策略考核試卷
- 2025年雞肉采購銷售合同范本
- 2025辦公室租賃合同模板()
- 2025新簽訂勞動合同模板示例
- 2025年學(xué)生會公關(guān)部廣告投放合同
- 瑜伽老師簽約合同協(xié)議
- 訂餐協(xié)議合同協(xié)議
- 房屋征拆合同協(xié)議
- 湖北省武漢市2025屆高中畢業(yè)生四月調(diào)研考試數(shù)學(xué)試卷及答案(武漢四調(diào))
- Unit 1 Growing up (Period 1)(教學(xué)設(shè)計)-2024-2025學(xué)年滬教牛津版(深圳用)英語六年級上冊
- 2025年水務(wù)行業(yè)化學(xué)檢驗(yàn)員職業(yè)技能競賽參考試題(附答案)
- 湖南湘潭高新集團(tuán)有限公司招聘考試真題2024
- 2025春季學(xué)期國開電大本科《政府經(jīng)濟(jì)學(xué)》一平臺在線形考(形考任務(wù)1至4)試題及答案
- 2025年中小學(xué)教師資格考試進(jìn)階試題及答案
- 創(chuàng)新創(chuàng)業(yè)實(shí)戰(zhàn)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- GB 21258-2024燃煤發(fā)電機(jī)組單位產(chǎn)品能源消耗限額
- DB34∕T 4010-2021 水利工程外觀質(zhì)量評定規(guī)程
評論
0/150
提交評論