Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Google¡¶AndroidÐÔÄÜÓÅ»¯¡·Ñ§Ï°±Ê¼Ç£¨Ï£©
 
×÷Õߣººú¿­ À´Ô´£ºCSDN ·¢²¼ÓÚ£º 2015-05-08
  2690  次浏览      27
 

ÄÚ´æÆª

1) Memory, GC, and Performance

ÖÚËùÖÜÖª£¬ÓëC/C++ÐèҪͨ¹ýÊÖ¶¯±àÂëÀ´ÉêÇëÒÔ¼°ÊÍ·ÅÄÚ´æÓÐËù²»Í¬£¬JavaÓµÓÐGCµÄ»úÖÆ¡£AndroidϵͳÀïÃæÓÐÒ»¸öGenerational Heap MemoryµÄÄ£ÐÍ£¬ÏµÍ³»á¸ù¾ÝÄÚ´æÖв»Í¬µÄÄÚ´æÊý¾ÝÀàÐÍ·Ö±ðÖ´Ðв»Í¬µÄGC²Ù×÷¡£ÀýÈ磬×î½ü¸Õ·ÖÅäµÄ¶ÔÏó»á·ÅÔÚYoung GenerationÇøÓò£¬Õâ¸öÇøÓòµÄ¶ÔÏóͨ³£¶¼ÊÇ»á¿ìËÙ±»´´½¨²¢ÇҺܿ챻Ïú»Ù»ØÊյģ¬Í¬Ê±Õâ¸öÇøÓòµÄGC²Ù×÷ËÙ¶ÈÒ²ÊDZÈOld GenerationÇøÓòµÄGC²Ù×÷Ëٶȸü¿ìµÄ¡£

³ýÁËËٶȲîÒìÖ®Í⣬ִÐÐGC²Ù×÷µÄʱºò£¬ËùÓÐÏ̵߳ÄÈκβÙ×÷¶¼»áÐèÒªÔÝÍ££¬µÈ´ýGC²Ù×÷Íê³ÉÖ®ºó£¬ÆäËû²Ù×÷²ÅÄܹ»¼ÌÐøÔËÐС£

ͨ³£À´Ëµ£¬µ¥¸öµÄGC²¢²»»áÕ¼ÓÃÌ«¶àʱ¼ä£¬µ«ÊÇ´óÁ¿²»Í£µÄGC²Ù×÷Ôò»áÏÔÖøÕ¼ÓÃÖ¡¼ä¸ôʱ¼ä(16ms)¡£Èç¹ûÔÚÖ¡¼ä¸ôʱ¼äÀïÃæ×öÁ˹ý¶àµÄGC²Ù×÷£¬ÄÇô×ÔÈ»ÆäËûÀàËÆ¼ÆË㣬äÖȾµÈ²Ù×÷µÄ¿ÉÓÃʱ¼ä¾Í±äµÃÉÙÁË¡£

2) Memory Monitor Walkthrough

Android StudioÖеÄMemory Monitor¿ÉÒԺܺõذïÖúÎÒÃDz鿴³ÌÐòµÄÄÚ´æÊ¹ÓÃÇé¿ö¡£

3) Memory Leaks

ÄÚ´æÐ¹Â©±íʾµÄÊDz»ÔÙÓõ½µÄ¶ÔÏóÒòΪ±»´íÎóÒýÓöøÎÞ·¨½øÐлØÊÕ¡£

·¢ÉúÄÚ´æÐ¹Â©»áµ¼ÖÂMemory GenerationÖеÄÊ£Óà¿ÉÓÃHeap SizeÔ½À´Ô½Ð¡£¬ÕâÑù»áµ¼ÖÂÆµ·±´¥·¢GC£¬¸ü½øÒ»²½ÒýÆðÐÔÄÜÎÊÌâ¡£

¾ÙÀýÄÚ´æÐ¹Â©£¬ÏÂÃæinit()·½·¨À´×Ôij¸ö×Ô¶¨ÒåView£º

private void init() {  
ListenerCollector collector = new ListenerCollector();
collector.setListener(this, mListener);
}

ÉÏÃæµÄÀý×ÓÈÝÒ×´æÔÚÄÚ´æÐ¹Â©£¬Èç¹ûactivityÒòΪÉ豸·­×ª¶øÖØÐ´´½¨£¬×Ô¶¨ÒåµÄView»á×Ô¶¯ÖØÐ°Ñд´½¨³öÀ´µÄmListener¸ø°ó¶¨µ½ListenerCollectorÖУ¬µ«Êǵ±activity±»Ïú»ÙµÄʱºò£¬mListenerÈ´ÎÞ·¨±»»ØÊÕÁË¡£

4) Heap Viewer Walkthrough

ÏÂͼÑÝʾÁËAndroid ToolsÀïÃæµÄHeap ViewerµÄ¹¦ÄÜ£¬ÎÒÃÇ¿ÉÒÔ¿´µ½µ±Ç°½ø³ÌÖеÄHeap SizeµÄÇé¿ö£¬·Ö±ðÓÐÄÄЩÀàÐ͵ÄÊý¾Ý£¬Õ¼±ÈÊǶàÉÙ¡£

5) Understanding Memory Churn

Memory ChurnÄÚ´æ¶¶¶¯£¬ÄÚ´æ¶¶¶¯ÊÇÒòΪÔÚ¶Ìʱ¼äÄÚ´óÁ¿µÄ¶ÔÏó±»´´½¨ÓÖÂíÉϱ»ÊÍ·Å¡£Ë²¼ä²úÉú´óÁ¿µÄ¶ÔÏó»áÑÏÖØÕ¼ÓÃYoung GenerationµÄÄÚ´æÇøÓò£¬µ±´ïµ½·§Öµ£¬Ê£Óà¿Õ¼ä²»¹»µÄʱºò£¬»á´¥·¢GC´Ó¶øµ¼Ö¸ղúÉúµÄ¶ÔÏóÓֺܿ챻»ØÊÕ¡£¼´Ê¹Ã¿´Î·ÖÅäµÄ¶ÔÏóÕ¼ÓÃÁ˺ÜÉÙµÄÄڴ棬µ«ÊÇËûÃǵþ¼ÓÔÚÒ»Æð»áÔö¼ÓHeapµÄѹÁ¦£¬´Ó¶ø´¥·¢¸ü¶àÆäËûÀàÐ͵ÄGC¡£Õâ¸ö²Ù×÷ÓпÉÄÜ»áÓ°Ïìµ½Ö¡ÂÊ£¬²¢Ê¹µÃÓû§¸ÐÖªµ½ÐÔÄÜÎÊÌâ¡£

½â¾öÉÏÃæµÄÎÊÌâÓмò½àÖ±¹Û·½·¨£¬Èç¹ûÄãÔÚMemory MonitorÀïÃæ²é¿´µ½¶Ìʱ¼ä·¢ÉúÁ˶à´ÎÄÚ´æµÄÕǵø£¬ÕâÒâζןÜÓпÉÄÜ·¢ÉúÁËÄÚ´æ¶¶¶¯¡£

ͬʱÎÒÃÇ»¹¿ÉÒÔͨ¹ýAllocation TrackerÀ´²é¿´ÔÚ¶Ìʱ¼äÄÚ£¬Í¬Ò»¸öÕ»Öв»¶Ï½ø³öµÄÏàͬ¶ÔÏó¡£ÕâÊÇÄÚ´æ¶¶¶¯µÄµäÐÍÐźÅÖ®Ò»¡£

µ±Äã´óÖ¶¨Î»ÎÊÌâÖ®ºó£¬½ÓÏÂÈ¥µÄÎÊÌâÐÞ¸´Ò²¾ÍÏÔµÃÏà¶ÔÖ±½Ó¼òµ¥ÁË¡£ÀýÈ磬ÄãÐèÒª±ÜÃâÔÚforÑ­»·ÀïÃæ·ÖÅä¶ÔÏóÕ¼ÓÃÄڴ棬ÐèÒª³¢Ê԰ѶÔÏóµÄ´´½¨ÒƵ½Ñ­»·ÌåÖ®Í⣬×Ô¶¨ÒåViewÖеÄonDraw·½·¨Ò²ÐèÒªÒýÆð×¢Ò⣬ÿ´ÎÆÁÄ»·¢Éú»æÖÆÒÔ¼°¶¯»­Ö´Ðйý³ÌÖУ¬onDraw·½·¨¶¼»á±»µ÷Óõ½£¬±ÜÃâÔÚonDraw·½·¨ÀïÃæÖ´Ðи´ÔӵIJÙ×÷£¬±ÜÃâ´´½¨¶ÔÏó¡£¶ÔÓÚÄÇЩÎÞ·¨±ÜÃâÐèÒª´´½¨¶ÔÏóµÄÇé¿ö£¬ÎÒÃÇ¿ÉÒÔ¿¼ÂǶÔÏó³ØÄ£ÐÍ£¬Í¨¹ý¶ÔÏó³ØÀ´½â¾öƵ·±´´½¨ÓëÏú»ÙµÄÎÊÌ⣬µ«ÊÇÕâÀïÐèҪעÒâ½áÊøÊ¹ÓÃÖ®ºó£¬ÐèÒªÊÖ¶¯ÊͷŶÔÏó³ØÖеĶÔÏó¡£

6) Allocation Tracker

¹ØÓÚAllocation Tracker¹¤¾ßµÄʹÓ㬲»Õ¹¿ªÁË£¬²Î¿¼ÏÂÃæµÄÁ´½Ó£º

http://developer.android.com/tools/debugging/ddms.html#alloc

http://android-developers.blogspot.com/2009/02/track-memory-allocations.html

7) Improve Your Code To Reduce Churn

ÏÂÃæÑÝʾһ¸öÀý×Ó£¬ÈçºÎͨ¹ýÐ޸ĴúÂëÀ´±ÜÃâÄÚ´æ¶¶¶¯¡£ÓÅ»¯Ö®Ç°µÄÄÚ´æ¼ì²âͼ£º

¶¨Î»´úÂëÖ®ºó£¬ÐÞ¸´ÁËStringÆ´½ÓµÄÎÊÌ⣺

ÓÅ»¯Ö®ºóµÄÄÚ´æ¼à²âͼ£º

8) Recap

ÉÏÃæÌáµ½ÁËÈýÖÖ²âÁ¿ÄÚ´æµÄ¹¤¾ß£¬ÏÂÃæÔÙ¼òÒª¸ÅÀ¨Ò»ÏÂËûÃǸ÷×ÔµÄÌØµã£º

1.Memory Monitor£º¸ú×ÙÕû¸öappµÄÄÚ´æ±ä»¯Çé¿ö¡£

2.Heap Viewer£º²é¿´µ±Ç°ÄÚ´æ¿ìÕÕ£¬±ãÓڶԱȷÖÎöÄÄЩ¶ÔÏóÓпÉÄÜ·¢ÉúÁËй©¡£

3.Allocation Tracker£º×·×ÙÄÚ´æ¶ÔÏóµÄÀ´Ô´¡£

µçÁ¿Æª

1) Understanding Battery Drain

ÊÖ»ú¸÷¸öÓ²¼þÄ£¿éµÄºÄµçÁ¿ÊDz»Ò»ÑùµÄ£¬ÓÐЩģ¿é·Ç³£ºÄµç£¬¶øÓÐЩģ¿éÔòÏà¶ÔÏԵúĵçÁ¿Ð¡ºÜ¶à¡£

µçÁ¿ÏûºÄµÄ¼ÆËãÓëͳ¼ÆÊÇÒ»¼þÂé·³¶øÇÒì¶ÜµÄÊÂÇ飬¼Ç¼µçÁ¿ÏûºÄ±¾ÉíÒ²ÊÇÒ»¸ö·ÑµçÁ¿µÄÊÂÇ顣Ψһ¿ÉÐеķ½°¸ÊÇʹÓõÚÈý·½¼à²âµçÁ¿µÄÉ豸£¬ÕâÑù²ÅÄܹ»»ñÈ¡µ½ÕæÊµµÄµçÁ¿ÏûºÄ¡£

µ±É豸´¦ÓÚ´ý»ú״̬ʱÏûºÄµÄµçÁ¿ÊǼ«Éٵģ¬ÒÔN5ΪÀý£¬´ò¿ª·ÉÐÐģʽ£¬¿ÉÒÔ´ý»ú½Ó½ü1¸öÔ¡£¿ÉÊǵãÁÁÆÁÄ»£¬Ó²¼þ¸÷¸öÄ£¿é¾ÍÐèÒª¿ªÊ¼¹¤×÷£¬Õâ»áÐèÒªÏûºÄºÜ¶àµçÁ¿¡£

ʹÓÃWakeLock»òÕßJobScheduler»½ÐÑÉ豸´¦Àí¶¨Ê±µÄÈÎÎñÖ®ºó£¬Ò»¶¨Òª¼°Ê±ÈÃÉ豸»Øµ½³õʼ״̬¡£Ã¿´Î»½ÐÑ·äÎÑÐźŽøÐÐÊý¾Ý´«µÝ£¬¶¼»áÏûºÄºÜ¶àµçÁ¿£¬Ëü±ÈWiFiµÈ²Ù×÷¸ü¼ÓµÄºÄµç¡£

2) Battery Historian

Battery HistorianÊÇAndroid 5.0¿ªÊ¼ÒýÈëµÄÐÂAPI¡£Í¨¹ýÏÂÃæµÄÖ¸Á¿ÉÒԵõ½É豸ÉϵĵçÁ¿ÏûºÄÐÅÏ¢£º

$ adb shell dumpsys batterystats > xxx.txt  //µÃµ½Õû¸öÉ豸µÄµçÁ¿ÏûºÄÐÅÏ¢
$ adb shell dumpsys batterystats > com.package.name > xxx.txt //µÃµ½Ö¸¶¨appÏà¹ØµÄµçÁ¿ÏûºÄÐÅÏ¢

µÃµ½ÁËԭʼµÄµçÁ¿ÏûºÄÊý¾ÝÖ®ºó£¬ÎÒÃÇÐèҪͨ¹ýGoogle±àдµÄÒ»¸öpython½Å±¾°ÑÊý¾ÝÐÅϢת»»³É¿É¶ÁÐÔ¸üºÃµÄhtmlÎļþ£º

$ python historian.py xxx.txt > xxx.html

´ò¿ªÕâ¸öת»»¹ýºóµÄhtmlÎļþ£¬¿ÉÒÔ¿´µ½ÀàËÆTraceViewÉú³ÉµÄÁбíÊý¾Ý£¬ÕâÀïµÄÊý¾ÝÐÅÏ¢Á¿ºÜ´ó£¬ÕâÀï¾Í²»Õ¹¿ªÁË¡£

3) Track Battery Status & Battery Manager

ÎÒÃÇ¿ÉÒÔͨ¹ýÏÂÃæµÄ´úÂëÀ´»ñÈ¡ÊÖ»úµÄµ±Ç°³äµç״̬£º

// 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!¡±);
}

ÔÚÉÏÃæµÄÀý×ÓÑÝʾÁËÈçºÎÁ¢¼´»ñÈ¡µ½ÊÖ»úµÄ³äµç״̬£¬µÃµ½³äµç״̬ÐÅÏ¢Ö®ºó£¬ÎÒÃÇ¿ÉÒÔÓÐÕë¶ÔÐԵĶԲ¿·Ö´úÂë×öÓÅ»¯¡£±ÈÈçÎÒÃÇ¿ÉÒÔÅжÏÖ»Óе±Ç°ÊÖ»úΪAC³äµç״̬ʱ ²ÅÈ¥Ö´ÐÐһЩ·Ç³£ºÄµçµÄ²Ù×÷¡£

/** 
* 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) Wakelock and Battery Drain

¸ßЧµÄ±£Áô¸ü¶àµÄµçÁ¿Óë²»¶Ï´ÙʹÓû§Ê¹ÓÃÄãµÄApp»áÏûºÄµçÁ¿£¬ÕâÊÇì¶ÜµÄÑ¡ÔñÌâ¡£²»¹ýÎÒÃÇ¿ÉÒÔʹÓÃһЩ¸üºÃµÄ°ì·¨À´Æ½ºâÁ½Õß¡£

¼ÙÉèÄãµÄÊÖ»úÀïÃæ×°ÁË´óÁ¿µÄÉç½»ÀàÓ¦Ó㬼´Ê¹ÊÖ»ú´¦ÓÚ´ý»ú״̬£¬Ò²»á¾­³£±»ÕâЩӦÓû½ÐÑÓÃÀ´¼ì²éͬ²½ÐµÄÊý¾ÝÐÅÏ¢¡£Android»á²»¶Ï¹Ø±Õ¸÷ÖÖÓ²¼þÀ´ÑÓ³¤ÊÖ»úµÄ´ý»úʱ¼ä£¬Ê×ÏÈÆÁÄ»»áÖ𽥱䰵ֱÖÁ¹Ø±Õ£¬È»ºóCPU½øÈë˯Ãߣ¬ÕâÒ»ÇвÙ×÷¶¼ÊÇΪÁ˽ÚÔ¼±¦¹óµÄµçÁ¿×ÊÔ´¡£µ«ÊǼ´Ê¹ÔÚÕâÖÖ˯Ãß״̬Ï£¬´ó¶àÊýÓ¦Óû¹Êǻ᳢ÊÔ½øÐй¤×÷£¬ËûÃǽ«²»¶ÏµÄ»½ÐÑÊÖ»ú¡£Ò»¸ö×î¼òµ¥µÄ»½ÐÑÊÖ»úµÄ·½·¨ÊÇʹÓÃPowerManager.WakeLockµÄAPIÀ´±£³ÖCPU¹¤×÷²¢·ÀÖ¹ÆÁÄ»±ä°µ¹Ø±Õ¡£ÕâʹµÃÊÖ»ú¿ÉÒÔ±»»½ÐÑ£¬Ö´Ðй¤×÷£¬È»ºó»Øµ½Ë¯Ãß״̬¡£ÖªµÀÈçºÎ»ñÈ¡WakeLockÊǼòµ¥µÄ£¬¿ÉÊǼ°Ê±ÊÍ·ÅWakeLockÒ²ÊǷdz£ÖØÒªµÄ£¬²»Ç¡µ±µÄʹÓÃWakeLock»áµ¼ÖÂÑÏÖØ´íÎó¡£ÀýÈçÍøÂçÇëÇóµÄÊý¾Ý·µ»ØÊ±¼ä²»È·¶¨£¬µ¼Ö±¾À´Ö»ÐèÒª10sµÄÊÂÇéÒ»Ö±µÈ´ýÁË1¸öСʱ£¬ÕâÑù»áʹµÃµçÁ¿°×°×ÀË·ÑÁË¡£ÕâÒ²ÊÇΪºÎʹÓôø³¬Ê±²ÎÊýµÄwakelock.acquice()·½·¨ÊǺܹؼüµÄ¡£

µ«Êǽö½öÉèÖó¬Ê±²¢²»×ã¹»½â¾öÎÊÌ⣬ÀýÈçÉèÖö೤µÄ³¬Ê±±È½ÏºÏÊÊ£¿Ê²Ã´Ê±ºò½øÐÐÖØÊԵȵȣ¿½â¾öÉÏÃæµÄÎÊÌ⣬ÕýÈ·µÄ·½Ê½¿ÉÄÜÊÇʹÓ÷Ǿ«×¼¶¨Ê±Æ÷¡£Í¨³£Çé¿öÏ£¬ÎÒÃÇ»áÉ趨һ¸öʱ¼ä½øÐÐij¸ö²Ù×÷£¬µ«ÊǶ¯Ì¬ÐÞ¸ÄÕâ¸öʱ¼äÒ²Ðí»á¸üºÃ¡£ÀýÈ磬Èç¹ûÓÐÁíÍâÒ»¸ö³ÌÐòÐèÒª±ÈÄãÉ趨µÄʱ¼äÍí5·ÖÖÓ»½ÐÑ£¬×îºÃÄܹ»µÈµ½ÄǸöʱºò£¬Á½¸öÈÎÎñÀ¦°óÒ»Æðͬʱ½øÐУ¬Õâ¾ÍÊǷǾ«È·¶¨Ê±Æ÷µÄºËÐŤ×÷Ô­Àí¡£ÎÒÃÇ¿ÉÒÔ¶¨ÖƼƻ®µÄÈÎÎñ£¬¿ÉÊÇϵͳÈç¹û¼ì²âµ½Ò»¸ö¸üºÃµÄʱ¼ä£¬Ëü¿ÉÒÔÍÆ³ÙÄãµÄÈÎÎñ£¬ÒÔ½ÚÊ¡µçÁ¿ÏûºÄ¡£

ÕâÕýÊÇJobScheduler APIËù×öµÄÊÂÇé¡£Ëü»á¸ù¾Ýµ±Ç°µÄÇé¿öÓëÈÎÎñ£¬×éºÏ³öÀíÏëµÄ»½ÐÑʱ¼ä£¬ÀýÈçµÈµ½ÕýÔÚ³äµç»òÕßÁ¬½Óµ½WiFiµÄʱºò£¬»òÕß¼¯ÖÐÈÎÎñÒ»ÆðÖ´ÐС£ÎÒÃÇ¿ÉÒÔͨ¹ýÕâ¸öAPIʵÏֺܶàÃâ·ÑµÄµ÷¶ÈËã·¨¡£

5) Network and Battery Drain

ÏÂÃæÄÚÈÝÀ´×Ô¹Ù·½TrainingÎĵµÖиßЧÏÂÔØÕ½ڹØÓÚÊÖ»ú(Radio)·äÎÑÐźŶԵçÁ¿ÏûºÄµÄ½éÉÜ¡£

ͨ³£Çé¿öÏ£¬Ê¹ÓÃ3GÒÆ¶¯ÍøÂç´«ÊäÊý¾Ý£¬µçÁ¿µÄÏûºÄÓÐÈýÖÖ״̬£º

1.Full power: ÄÜÁ¿×î¸ßµÄ״̬£¬Òƶ¯ÍøÂçÁ¬½Ó±»¼¤»î£¬ÔÊÐíÉ豸ÒÔ×î´óµÄ´«ÊäËÙÂʽøÐвÙ×÷¡£

2.Low power: Ò»ÖÖÖмä״̬£¬¶ÔµçÁ¿µÄÏûºÄ²î²»¶àÊÇFull power״̬ϵÄ50%¡£

3.Standby: ×îµÍµÄ״̬£¬Ã»ÓÐÊý¾ÝÁ¬½ÓÐèÒª´«Ê䣬µçÁ¿ÏûºÄ×îÉÙ¡£

ÏÂͼÊÇÒ»¸öµäÐ͵Ä3G Radio State MachineµÄͼʾ(À´×ÔAT&T£¬ÏêÇéÇëµã»÷ÕâÀï)£º

×ÜÖ®£¬ÎªÁ˼õÉÙµçÁ¿µÄÏûºÄ£¬ÔÚ·äÎÑÒÆ¶¯ÍøÂçÏ£¬×îºÃ×öµ½ÅúÁ¿Ö´ÐÐÍøÂçÇëÇ󣬾¡Á¿±ÜÃâÆµ·±µÄ¼ä¸ôÍøÂçÇëÇó¡£

ͨ¹ýÇ°ÃæÑ§Ï°µ½µÄBattery HistorianÎÒÃÇ¿ÉÒԵõ½É豸µÄµçÁ¿ÏûºÄÊý¾Ý£¬Èç¹ûÊý¾ÝÖеÄÒÆ¶¯·äÎÑÍøÂç(Mobile Radio)µçÁ¿ÏûºÄ³ÊÏÖÏÂÃæµÄÇé¿ö£¬¼ä¸ôºÜС£¬ÓÖÆµ·±¶Ï¶ÏÐøÐøµÄ³öÏÖ£¬ËµÃ÷µçÁ¿ÏûºÄÐÔÄܺܲ»ºÃ£º

¾­¹ýÓÅ»¯Ö®ºó£¬Èç¹û³ÊÏÖÏÂÃæµÄͼʾ£¬ËµÃ÷µçÁ¿ÏûºÄµÄÐÔÄÜÊÇÁ¼ºÃµÄ£º

ÁíÍâWiFiÁ¬½ÓÏ£¬ÍøÂç´«ÊäµÄµçÁ¿ÏûºÄÒª±ÈÒÆ¶¯ÍøÂçÉٺܶ࣬Ӧ¸Ã¾¡Á¿¼õÉÙÒÆ¶¯ÍøÂçϵÄÊý¾Ý´«Ê䣬¶àÔÚWiFi»·¾³Ï´«ÊäÊý¾Ý¡£

ÄÇôÈçºÎ²ÅÄܹ»°ÑÈÎÎñ»º´æÆðÀ´£¬×öµ½ÅúÁ¿»¯Ö´ÐÐÄØ£¿ÏÂÃæ¾ÍÂÖµ½Job Scheduler³ö³¡ÁË¡£

6) Using Job Scheduler

ʹÓÃJob Scheduler£¬Ó¦ÓÃÐèÒª×öµÄÊÂÇé¾ÍÊÇÅжÏÄÄЩÈÎÎñÊDz»½ô¼±µÄ£¬¿ÉÒÔ½»¸øJob SchedulerÀ´´¦Àí£¬Job Scheduler¼¯Öд¦ÀíÊÕµ½µÄÈÎÎñ£¬Ñ¡ÔñºÏÊʵÄʱ¼ä£¬ºÏÊʵÄÍøÂ磬ÔÙÒ»Æð½øÐÐÖ´ÐС£

ÏÂÃæÊÇʹÓÃJob SchedulerµÄÒ»¶Î¼òҪʾÀý£¬ÐèÒªÏÈÓÐÒ»¸ö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("https://www.google.com");
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´¥·¢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 MyJobService in the startJob() method. For
* example, to poll your server, you would create the network connection, send your GET
* request, and then process the response all in MyJobService. This allows the JobScheduler API
* to invoke your logic without needed to restart your activity.
*
* For brevity in the sample, we are scheduling the same job several times in quick succession,
* but again, try to consider similar tasks occurring over time in your application that can
* afford to wait and may benefit from batching.
*/
public void pollServer() {
JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
for (int i=0; i<10; i++) {
JobInfo jobInfo = new JobInfo.Builder(i, mServiceComponent)
.setMinimumLatency(5000) // 5 seconds
.setOverrideDeadline(60000) // 60 seconds (for brevity in the sample)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) // WiFi or data connections
.build();

mWakeLockMsg.append("Scheduling job " + i + "!\n");
scheduler.schedule(jobInfo);
}
}
}
   
2690 ´Îä¯ÀÀ       27
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢ 6-12[ÏÃÃÅ]
È˹¤ÖÇÄÜ.»úÆ÷ѧϰTensorFlow 6-22[Ö±²¥]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 6-30[±±¾©]
ǶÈëʽÈí¼þ¼Ü¹¹-¸ß¼¶Êµ¼ù 7-9[±±¾©]
Óû§ÌåÑé¡¢Ò×ÓÃÐÔ²âÊÔÓëÆÀ¹À 7-25[Î÷°²]
ͼÊý¾Ý¿âÓë֪ʶͼÆ× 8-23[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ

ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ