Android Performance Optimization Tour 5--power optimization

Source: Internet
Author: User
Tags install go new set
This is a creation in Article, where the information may have evolved or changed.


First, preface



When the phone is running, the hardware consumes power when it handles a variety of tasks. Users can view battery usage by using their own battery monitoring function:



Battery usage (MI). png


Once the user discovers that your app consumes a lot of power, it can be a hassle. Therefore, we need to design the app, we should work hard to fully consider the problem of power optimization.



Theory and analysis of electricity consumption



The key to writing low-power applications is to have a thorough understanding of its theory and the whole process. The following is an introduction to the theoretical knowledge of power consumption.



1, the concept of power consumption



The first thing to know, the consumption of electricity, mainly refers to the power consumption of hardware (nonsense), in the electronic world, this hardware consumes power to perform the task of the process, called the time-out current consumption.



Hardware consumes power. png


In different cases, the amount of power consumed is different in the same time. For example, using flight mode standby, you can really stick to more than 10 days. But once we use the phone, such as using cellular wireless data exchange (3G4G), the screen to stay awake, and so on, the battery will be consumed quickly:



Power consumption analysis. png


As a developer, we'd like to know what tasks my app is performing that consumes the most power? The problem is really tricky.



Power optimization is all aspects, such as reducing the overhead of memory and reducing the excessive drawing of the interface, which is itself a kind of power optimization.



2. Calculation of Power consumption



The calculation and statistics of power consumption is a troublesome and contradictory thing, the recording of power consumption itself is also a charge of the matter (so many mobile phone customization system to the monitoring of the power of the function castrated).



The only viable option is to use a third-party monitoring device so that it can get real power consumption (because third-party hardware is monitored by its own power instead of the battery used by the phone). Use a power meter, for example.



When you turn on the screen, all the actions that you want to work with CPU/GPU will wake the screen, which consumes power. This is not the same as the application code wakeup device. such as the use of wake-up alarm clock (wake clock), Alarmmanager, Jobschedulerapi. It is therefore difficult to know the true power consumption of your application.



3, equipment standby and wake-up power consumption analysis



Why take this alone to speak, is because, wake up this moment is very power consumption, the following allow me to introduce slowly.



Let's take a look at the power consumption of the standby state:



Standby state power consumption. png


In the standby state, the amount of electricity consumed is very low, which is beyond doubt.



After using and waking the screen:



The screen wakes up. png


As you can see, the screen wakes up for a moment that is very power-hungry, and there is a spike in electricity usage.



Here's a look at the CPU wake-up curve (the CPU wakes up and the screen doesn't necessarily wake up):



CPU wake. png


Similarly, when the CPU wakes up, there will also be a power usage peak line.



After the CPU wakes up:



After wake. png


After the CPU wakes up, the power consumption of the device does not occur when the peak line wakes up.



It is important to note that when the work is done, the device will actively hibernate, which is very significant, and keeping the screen awake for a long time can quickly consume the battery when not in use or rarely used.



Conclusion



The instant the device wakes up is a spike in consumption, so when your work needs to continue, you can consider staying awake.



4. Wireless Cellular power Consumption analysis



Cellular Wireless is also a terrible power consumption, even more power than WiFi, so here alone to analyze.



Tips: When not using traffic, it is best to close the data, which saves power and saves traffic.



The following begins the process of analyzing wireless cellular power consumption:



Wireless cellular power consumption process. png


As shown in the following:


    1. When a device sends data over a wireless network, there is a wake-up spike in order to use the hardware.
    2. Next there is a high value, which is the amount of power that is consumed by the sending packet.
    3. Then accepting the packet also consumes a lot of power and sees a spike.
    4. Maintain wake-up state, power consumption is relatively balanced, very few peak points.


So we turn on the wireless mode this process is very power consumption, then the hardware in order to prevent frequent turn off power consumption, took a helpless approach, will be in a small period of time to maintain the open mode, to prevent a short period of time there is a packet need to receive. This data is very useful, but not all developers have this third-party device tracking. But with the Android L version, you can use a new set of tools to optimize your application's power consumption. (obviously don't consider the compatibility issue here, I just want to measure the power consumption problem, the same app on different versions of Android power consumption should not be too much impact, although different Android version of the battery optimization is different, but our analysis object is our own app itself)



Three, the Power Analysis tool battery historian environment construction and use



Battery Historian (Https://github.com/google/battery-historian) is a power usage record analysis tool. The data obtained through ADB can be viewed and analyzed directly by the browser using the battery historian tool to analyze and process the resulting HTML results files.



1. Environment construction



There are two ways to install it through Docker or by compiling the source code.



Install via Docker (recommended for Mac or Linux)



Docker is a container that is typically used for cloud computing and big data platforms. One of the ideas advocated is: Software as a service. This sentence is not covered, a word can be released by others Docker service environment all copy come over (note is the entire software environment, equivalent to copy an identical host, even the software is not installed, all have. )
However, for Windows users, Docker only supports WINDOWS10. Generally recommended for use on Mac or Linux.



The command to open this Docker service is as follows:



docker -- run -p <port>:9999 gcr.io/android-battery-historian/stable:3.0 --port 9999


Above this is the temporary opening of the program service, you can also add the-d parameter, open a separate system services more formal services.



Install by compiling the source code (recommended for use on Windows)


    • Install GO Environment


Download the Go installer to the official website: https://golang.org/dl/, this gives the download path for version 1.9 Https://golang.org/doc/install?download=go1.9.windows-amd64.msi.



To configure environment variables:


    1. The role of Goroot:goroot is to tell the GO command and other related tools where to find the go package installed on your system, so here is the Go installation directory.
    2. Gopath:gopath can be simply understood as a catalog of projects, so you need to manually create a go project path.
    3. Path: Place the bin directory of Go into the PATH environment variable.


After installation, enter the following command to check if the GO environment is properly installed:



go version
    • Install Git


Refer to Liaoche's blog here.


    • Install Python2.7 (note not Python3)


Refer to Liaoche's blog here, and note adding Python to path.


    • Installing the Java Environment


There's nothing to say about this.


    • Download the source code and run


Download the battery historian source code using the GO command below and compile the run:



go get -d -u github.com/google/battery-historian/...


Tips: Download to the Gopath configuration directory.



To switch directories:



cd $GOPATH/src/github.com/google/battery-historian


Execute the configuration script (compile), and note that this process may require flipping the wall:



go run setup.go


Start Battery Historian:



go run cmd/battery-historian/battery-historian.go


At this time, open the browser, enter http://127.0.0.1:9999/, display the following page represents the successful installation (need to access Google's static resources, need to flip the wall):



Environment set up a good example. png


2. Data acquisition


    • Initialization


The Battery-historian tool needs to use the battery history in Bugreport, so the following actions are required.



To restart the ADB service:



adb kill-serveradb start-server


This step is important because it opens up a lot of things that can cause conflicts when we develop a battery record. We re-start the ADB for the sake of insurance.



Use the following command to turn on battery data acquisition and reset:



adb shell dumpsys batterystats --enable full-wake-historyadb shell dumpsys batterystats --reset


The above actions are important because you can filter out unwanted data. Then disconnect the data cable (preventing the data line from interfering with charge and discharge data) and run your own app for testing.


    • Get Data


Reconnect USB debugging and get the data using the following command:



adb bugreport bugreport.zip(6.0以及以下的,使用txt)


Note: Under 7.0, you need to use the old version of the ADB tool, otherwise you can not capture, reference article http://blog.csdn.net/mwq30123/article/details/53888449



Note: The official SDK document export file is: adb shell Dumpsys batterystats > Batterystats.txt. Use Python historian.py batterystats.txt > batterystats.html to view data. This is how the old version of Battery-historian is used. Currently battery historian has updated version 2.0, we recommend using Bugreport method to export data analysis, you can see more information.



Note: The emulator may not get useful power data, and the webpage does not display the battery information as shown in: (You may need a physical phone)



Power analysis. png
    • Upload the data for analysis


The final step is to open the http://127.0.0.1:9999/and submit the data for testing.



Battery analysis (based on V2.0 version of battery historian)



It is not easy to come up all the way, the author is also stepping on a lot of pits to come over, so what is the problem in spite of my blog under the message, I try to answer each.



The new version of the Power analysis interface looks like this:



Battery analysis interface. png


Several important parameters that we need to be concerned with are explained:


    • The operating state of the CPU running:cpu and whether it is awakened. If you put the mouse on the top, you can see more information, such as the cause of CPU wake.
    • Wakelock: Wake-up lock
    • Screen: Is the display turned on
    • Top app: Current top-level app
    • Mobile Network type: network types, where it is important to note that the "free network may include WiFi, Bluetooth network sharing, USB tethering"
    • Mobile Radio Active: moving Cellular signals
    • WiFi Supplicant:wifi is turned on
    • WiFi Signal Strength:wifi Strength
    • Audio: Whether the sound is turned on
    • Battery Level: Power
    • Plugged: Charging type, including AC (charger), USB, other (such as wireless charging), can be seen when the mouse is on the top
    • The bottom of the horizontal axis is the time


Recommendations for Analysis:


    • When you find a dense, constantly waking CPU, you may need to optimize it (wake-up lock)
    • Are some services executed after charging the power?
    • Use of the network and power, etc.
    • Does the screen always light up?


Iv. Power Optimization Recommendations



When the Android device is idle, the screen dims, then turns off the screen, and finally stops the CPU from running, which prevents the battery from draining quickly. The timer, Handler, Thread, service, and so on, which are customized during hibernation, will be paused. But there are times when we need to change the default state of the Android system: for example, we need to keep the screen lit when playing a game, such as some downloads that don't require a solid screen but require the CPU to run until the task is complete. This prevents more electricity from being consumed by the moment of awakening.



1. Judging the charging status



In order to save power, some work (do not need to interact with the user in a timely manner) can be placed when the phone plugged into the power of the time to do. such as mobile phone helper class items, automatic cleaning of mobile phone garbage, automatic backup upload pictures, contacts wait for the cloud and other code, you can wait for the user to charge and network time to execute, determine whether the code of charging is as follows:



Private boolean checkForPower() {
     / / Get the battery's charge status (register a broadcast)
     IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
     Intent res = this.registerReceiver(null, filter);

     / / Determine the state of charge by using the parameter information of the BatteryManager
     If (res != null) {
         Int chargePlug = res.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
         Boolean usb = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;//usb charging
         Boolean ac = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;//AC
         //Wireless charging, this requires API>=17
         Boolean wireless = false;
         If (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             Wireless = chargePlug == BatteryManager.BATTERY_PLUGGED_WIRELESS;
         }
         Return (usb || ac || wireless);
     } else {
         Return false;
     }
}


The code that determines whether the network is connected is as follows:



Private boolean isNetWorkConnected() {
     / / Determine the network connection
     ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
     Return (activeNetworkInfo != null && activeNetworkInfo.isConnected());
}


You need to add permissions:



<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>


2. Keep the screen solid



To prevent the screen from waking up in the blink of an energy, there are applications such as games and payment pages that need to keep the screen solid to conserve power:



getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);


It can also be used inside a layout file, but not as flexible:



android:keepScreenOn="true"


Note: Generally do not need to remove flag_keep_screen_on Flag,windowmanager will manage the program into the background back to the operation of the foreground. If you do need to clear the solid FLAG manually, use GetWindow (). Clearflags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)



3.1. Using Wake_lock



To conserve power, the CPU automatically enters hibernation when no task is busy. When a task needs to wake up the CPU to perform efficiently, the CPU is wake_lock locked. Wake_lock lock is mainly relative to the sleep of the system, meaning that my program to the CPU added this lock system will not hibernate, so that the purpose is to fully cooperate with the operation of our program. In some cases, if you do not do so, there will be some problems, such as the timely communication of the heartbeat pack will be put off the screen shortly after the network access and other issues. So inside there is a lot of use to the Wake_lock lock.



PowerManager the wake-up lock (Wake locks) feature of this system service to keep the CPU awake. Wake-up lock allows program control of the power state of the host device. Creating and holding a wake-up lock has a significant effect on the battery life, so it is only used when the task is completed in the background in the shortest possible time, unless it is really necessary to wake the lock. For example, there is no need to use it in acitivity. A typical representation is that the background service continues to keep the CPU running after the screen is closed.



If you do not use a wake-up lock to perform a background service, there is no guarantee that the task will stop at some point in the future due to CPU hibernation, which is not what we want. (Some people may think that the background services previously written did not have a chain to run very well, 1. It may be your task time is relatively short; 2. The CPU may be in the wake of many other software on the phone).



Among these, there are several types of wake locks:



Type of wake-up lock. png


Wake_lock Two kinds of locks (from the point of release, use):


    • A count lock
    • Non-counting lock (locks many times, only need release once can be relieved)


Tips: Please note that starting with API level 17, Full_wake_lock will be deprecated and should be replaced with flag_keep_screen_on.



To sum up, in order to prevent the CPU wake up power consumption, in the execution of critical code, in order to prevent the CPU sleep, need to use wake-up lock to save battery:



/ / Create a wake lock
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "partial_lock");

/ / Get the wake lock
wakeLock.acquire();

//some key code

/ / Release the wake lock
wakeLock.release();


You need to add permissions:



<uses-permission android:name="android.permission.WAKE_LOCK"/>


Tips: Getting and releasing a wake-up lock needs to appear in pairs



Tips: There are some unexpected situations, such as Xiaomi phone is to do a sync heartbeat pack (heartbeat alignment) (if more than the frequency of this synchronization will be blocked or reduced frequency), all the app background wake frequency can not be too high, this time need to reduce frequency, such as every 2S to request.



3.2. Using Wakefulbroadcastreceiver



As mentioned above, the typical usage scenario is that the backend service needs to keep the CPU running, The recommended approach is to use Wakefulbroadcastreceiver: a combination of broadcast and service (typical Intentservice) allows you to manage the lifecycle of your backend services well.



Wakefulbroadcastreceiver is a special case of broadcastreceiver. It will create and manage a partial_wake_lock type of Wakelock for your app. Wakefulbroadcastreceiver the work to the service (usually Intentservice) and ensures that the device does not go into hibernation during the handover. If you do not hold wakelock, it is easy for the device to hibernate before the task is done. The end result is that your app doesn't know when it will be able to get the job done, believing it's not what you want.



Example:



Service:



Public class MyIntentService extends IntentService {

     Public MyIntentService(String name) {
         Super(name);
     }

     Public MyIntentService() {
         Super(MyIntentService.class.getSimpleName());
     }

     @Override
     Protected void onHandleIntent(@Nullable Intent intent) {
         If (intent != null) {
             / / Get parameters
             Bundle extras = intent.getExtras();

             / / Execute some code that requires the CPU to stay awake

             //Execution ends, release wake lock
             MyWakefulReceiver.completeWakefulIntent(intent);
         }
     }
}


Broadcast recipient:



public class MyWakefulReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, MyIntentService.class);
        startWakefulService(context, service);
    }

}


When you need to use the service, you can do it in the usual way:



Intent intent = new Intent(this, MyIntentService.class);
/ / Pass parameters
intent.setData(Uri.parse("xxx"));


Tips: Note Adding permissions



Tips: Pay attention to the registration of services and broadcasts



Tips: Using broadcast to design is to understand the coupling



3.3, a large number of high-frequency CPU wake-up and operation using JOBSCHEDULER/GCM



A large number of high-frequency CPU wake-up and operation, we can take some algorithms to solve, these operations are arranged in a point-in-time centralized processing, rather than separate processing (which can prevent the power consumption of wake-up).



We can use the Jobscheduler or GCM provided by Google to achieve such a function.



Here is an example of a frequently requested network:



This is a service that requests a network:


Public class MyJobService extends JobService {
    Private static final String TAG = "MyJobService";

    @Override
    Public void onCreate() {
        super.onCreate();
        Log.i(TAG, "MyJobService created");
    }

    @Override
    Public void onDestroy() {
        super.onDestroy();
        Log.i (TAG, "MyJobService destroyed");
    }

    /**
     * Turn on time-consuming operation
     * @param params
     * @return
     */
    @Override
    Public boolean onStartJob(JobParameters params) {
        Log.i(TAG, "onStartJob:" + params.getJobId());
        If (isNetworkConnected()) {
            New SimpleDownloadTask() .execute(params);
            Return true;
        } else {
            Log.i(TAG, "No connection:" + params.getJobId());
        }
        Return false;
    }

    /**
     * JobFinish will callback before calling
     * @param params
     * @return
     */
    @Override
    Public boolean onStopJob(JobParameters params) {
        Log.i(TAG, "onStopJob:" + params.getJobId());
        Return false;
    }

    Private boolean isNetworkConnected() {
        ConnectivityManager connectivityManager =
                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        Return (networkInfo != null && networkInfo.isConnected());
    }

    Private class SimpleDownloadTask extends AsyncTask<JobParameters, Void, String> {

        Protected JobParameters mJobParam;

        @Override
        Protected String doInBackground(JobParameters... params) {
            mJobParam = params[0];
            Try {
                InputStream is = null;
                Int len = 50;

                URL url = new URL("https://www.baidu.com");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(10000); //10sec
                conn.setConnectTimeout(15000); //15sec
                conn.setRequestMethod("GET");

                Conn.connect();
                Int response = conn.getResponseCode();
                Log.d(TAG, "The response is: " + response);
                Is = conn.getInputStream();

                Reader reader = new InputStreamReader(is, "UTF-8");
                Char[] buffer = new char[len];
                Reader.read(buffer);
                Return new String(buffer);

            } catch (IOException e) {
                e.printStackTrace();
                Return null;
            }
        }

        @Override
        Protected void onPostExecute(String result) {
            / / End the task
            jobFinished(mJobParam, false);
            Log.i(TAG, result);
        }
    }
}


The following loop simulates the frequent invocation:



ComponentName serviceComponent = new ComponentName(this,MyJobService.class);
// frequently wake up
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
For (int i = 0; i < 500; i++) {
     JobInfo jobInfo = new JobInfo.Builder(i,serviceComponent)
             .setMinimumLatency(5000)//minimum delay 5 seconds
             .setOverrideDeadline(60000)//Maximum execution time 60 seconds
             //.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)//Free network---wifi Bluetooth USB
             .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)//Any Network---wifi
             .build();
     jobScheduler.schedule(jobInfo);
}


4, use Alarmmanager to wake up



When the machine does not operate for a period of time, it will go to sleep state. Polling to the server stops, long connections are broken, and in order to prevent this, you can use Alarmmanager:



Intent intent = new Intent(this, TestService.class);
PendingIntent pi = PendingIntent.getService(this, 0, intent, 0);

AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Am.cancel(pi);

//The alarm will wake up the system and perform the prompt function when the system is in sleep state.
//Fuzzy time, setRepeating is inaccurate in API-19 and before.
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, 2000, pi);
/ / Accurate time, but need to use after API-17
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, pi);
Am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, pi); 


The timer can start service services, send broadcasts, jump activity, and wake the system in a system sleep state. Therefore, this method does not need to acquire the power lock and release the Power lock.



For more information on Alarmmanager, please refer to the other articles.



In more than 19 versions, the frequency set in Setrepeating is only the recommended value (6.0 of the source of the minimum value is 60s), if you want to use Setwindow or setexact precision.



5. Other optimization



Of course, battery optimization is included in many aspects, such as:


    • Rendering optimization
    • Positioning Strategy Optimization
    • Network optimization, such as network cache processing, request mode, number of times optimized, set timeout, etc.
    • Code Execution Efficiency Optimization
    • Prevent memory leaks


Wait, power optimization is everywhere.



Deepening



First Android phones have two processors, one called Application Processor (AP), one called Baseband Processor (BP). The AP is an arm-architected processor for running the linux+android system, and BP is used to run a real-time operating system (RTOS), and the communication stack runs on the BP RTOS. Non-talk time, BP's energy consumption is basically around 5mA, and the AP as long as the non-dormant state, energy consumption at least 50mA, the implementation of graphics operations will be higher. In addition, the LCD operating power consumption around 100mA, WiFi is also around 100mA. When the phone is in standby, the AP, LCD, WiFi all go into hibernation, and the code of the app in Android will stop executing.


    • In order to ensure the proper execution of critical code in the application, Android provides the API for Wake Lock, which allows the application to have permission to prevent the AP from entering hibernation through code. However, if you do not understand the intentions of the Android designer to misuse the wake Lock API, in order to its own program in the background of the normal operation and long time to prevent the AP into hibernation, will become a standby battery killer. For example, an application of the previous period, such as the one that is still doing it.
    • Alarmmanager is an Android-encapsulated module for managing RTC, the RTC (Real time Clock) is a stand-alone hardware clock that can function when the CPU sleeps and wakes the CPU at a preset time when it arrives. (The Aurora push is used to do this.) )


Summarize:


    1. The execution of critical logic requires wake lock to protect it. Re-login if wire break is connected again
    2. How do I wake up to perform a task in hibernation? With Alarmmanager. such as the acquisition of push messages


Finally, the wakelock in the phone can be seen through the Wakelock Detector (WLD) Software:



Wld.png


Reference article:



Http://www.jianshu.com/p/ded0ed6fac3d
Http://www.jianshu.com/p/5b8bfa6a6c37
http://www.jianshu.com/p/ Fc2a4d191e18


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.