【移動應用開發(fā)技術】Android性能優(yōu)化電量的方法是什么_第1頁
【移動應用開發(fā)技術】Android性能優(yōu)化電量的方法是什么_第2頁
【移動應用開發(fā)技術】Android性能優(yōu)化電量的方法是什么_第3頁
【移動應用開發(fā)技術】Android性能優(yōu)化電量的方法是什么_第4頁
【移動應用開發(fā)技術】Android性能優(yōu)化電量的方法是什么_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

【移動應用開發(fā)技術】Android性能優(yōu)化電量的方法是什么

本文在下為大家詳細介紹“Android性能優(yōu)化電量的方法是什么”,內容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“Android性能優(yōu)化電量的方法是什么”文章能幫助大家解決疑惑,下面跟著在下的思路慢慢深入,一起來學習新知識吧。1)UnderstandingBatteryDrain手機各個硬件模塊的耗電量是不一樣的,有些模塊非常耗電,而有些模塊則相對顯得耗電量小很多。電量消耗的計算與統(tǒng)計是一件麻煩而且矛盾的事情,記錄電量消耗本身也是一個費電量的事情。唯一可行的方案是使用第三方監(jiān)測電量的設備,這樣才能夠獲取到真實的電量消耗。當設備處于待機狀態(tài)時消耗的電量是極少的,以N5為例,打開飛行模式,可以待機接近1個月。可是點亮屏幕,硬件各個模塊就需要開始工作,這會需要消耗很多電量。使用WakeLock或者JobScheduler喚醒設備處理定時的任務之后,一定要及時讓設備回到初始狀態(tài)。每次喚醒蜂窩信號進行數據傳遞,都會消耗很多電量,它比WiFi等操作更加的耗電。2)BatteryHistorianBatteryHistorian是Android5.0開始引入的新API。通過下面的指令,可以得到設備上的電量消耗信息:$

adb

shell

dumpsys

batterystats

>

xxx.txt

//得到整個設備的電量消耗信息

$

adb

shell

dumpsys

batterystats

>

>

xxx.txt

//得到指定app相關的電量消耗信息得到了原始的電量消耗數據之后,我們需要通過Google編寫的一個python腳本把數據信息轉換成可讀性更好的html文件:$

python

historian.py

xxx.txt

>

xxx.html打開這個轉換過后的html文件,可以看到類似TraceView生成的列表數據,這里的數據信息量很大,這里就不展開了。3)TrackBatteryStatus&BatteryManager我們可以通過下面的代碼來獲取手機的當前充電狀態(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!”);

}在上面的例子演示了如何立即獲取到手機的充電狀態(tài),得到充電狀態(tài)信息之后,我們可以有針對性的對部分代碼做優(yōu)化。比如我們可以判斷只有當前手機為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會消耗電量,這是矛盾的選擇題。不過我們可以使用一些更好的辦法來平衡兩者。假設你的手機里面裝了大量的社交類應用,即使手機處于待機狀態(tài),也會經常被這些應用喚醒用來檢查同步新的數據信息。Android會不斷關閉各種硬件來延長手機的待機時間,首先屏幕會逐漸變暗直至關閉,然后CPU進入睡眠,這一切操作都是為了節(jié)約寶貴的電量資源。但是即使在這種睡眠狀態(tài)下,大多數應用還是會嘗試進行工作,他們將不斷的喚醒手機。一個最簡單的喚醒手機的方法是使用PowerManager.WakeLock的API來保持CPU工作并防止屏幕變暗關閉。這使得手機可以被喚醒,執(zhí)行工作,然后回到睡眠狀態(tài)。知道如何獲取WakeLock是簡單的,可是及時釋放WakeLock也是非常重要的,不恰當的使用WakeLock會導致嚴重錯誤。例如網絡請求的數據返回時間不確定,導致本來只需要10s的事情一直等待了1個小時,這樣會使得電量白白浪費了。這也是為何使用帶超時參數的wakelock.acquice()方法是很關鍵的。但是僅僅設置超時并不足夠解決問題,例如設置多長的超時比較合適?什么時候進行重試等等?解決上面的問題,正確的方式可能是使用非精準定時器。通常情況下,我們會設定一個時間進行某個操作,但是動態(tài)修改這個時間也許會更好。例如,如果有另外一個程序需要比你設定的時間晚5分鐘喚醒,***能夠等到那個時候,兩個任務捆綁一起同時進行,這就是非精確定時器的核心工作原理。我們可以定制計劃的任務,可是系統(tǒng)如果檢測到一個更好的時間,它可以推遲你的任務,以節(jié)省電量消耗。這正是JobSchedulerAPI所做的事情。它會根據當前的情況與任務,組合出理想的喚醒時間,例如等到正在充電或者連接到WiFi的時候,或者集中任務一起執(zhí)行。我們可以通過這個API實現很多免費的調度算法。5)NetworkandBatteryDrain下面內容來自官方Training文檔中高效下載章節(jié)關于手機(Radio)蜂窩信號對電量消耗的介紹。通常情況下,使用3G移動網絡傳輸數據,電量的消耗有三種狀態(tài):Fullpower:能量***的狀態(tài),移動網絡連接被激活,允許設備以***的傳輸速率進行操作。Lowpower:一種中間狀態(tài),對電量的消耗差不多是Fullpower狀態(tài)下的50%。Standby:***的狀態(tài),沒有數據連接需要傳輸,電量消耗最少。下圖是一個典型的3GRadioStateMachine的圖示總之,為了減少電量的消耗,在蜂窩移動網絡下,***做到批量執(zhí)行網絡請求,盡量避免頻繁的間隔網絡請求。通過前面學習到的BatteryHistorian我們可以得到設備的電量消耗數據,如果數據中的移動蜂窩網絡(MobileRadio)電量消耗呈現下面的情況,間隔很小,又頻繁斷斷續(xù)續(xù)的出現,說明電量消耗性能很不好:經過優(yōu)化之后,如果呈現下面的圖示,說明電量消耗的性能是良好的:另外WiFi連接下,網絡傳輸的電量消耗要比移動網絡少很多,應該盡量減少移動網絡下的數據傳輸,多在WiFi環(huán)境下傳輸數據。那么如何才能夠把任務緩存起來,做到批量化執(zhí)行呢?下面就輪到JobScheduler出場了。6)UsingJobScheduler使用JobScheduler,應用需要做的事情就是判斷哪些任務是不緊急的,可以交給JobScheduler來處理,JobScheduler集中處理收到的任務,選擇合適的時間,合適的網絡,再一起進行執(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);

}

}

}然后模擬通過點擊Button觸發(fā)N個任務,交給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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論