ניהול צריכת חשמל באפליקציה

באנדרואיד 9 ומעלה, הפלטפורמה יכולה לנטר אפליקציות להתנהגות המשפיעה לרעה על חיי הסוללה של מכשירים. הפלטפורמה משתמשת ומעריכה בכללי הגדרה כדי לספק זרימת UX המעניקה למשתמשים אפשרות להגביל אפליקציות שמפרות את הכללים.

באנדרואיד 8.0 ומטה, היו הגבלות דרך תכונות כמו Doze, המתנה לאפליקציה, מגבלות רקע ומגבלות מיקום ברקע. עם זאת, חלק מהאפליקציות המשיכו להפגין התנהגויות רעות, חלקן מתוארות ב- Android vitals . אנדרואיד 9 הציגה תשתית מערכת הפעלה שיכולה לזהות ולהגביל אפליקציות על סמך כללי הגדרה שניתן לעדכן לאורך זמן.

הגבלות רקע

משתמשים יכולים להגביל אפליקציות, או שהמערכת עשויה להציע אפליקציות שהיא מזהה משפיעות לרעה על תקינות המכשיר.

אפליקציות מוגבלות:

  • עדיין ניתן להפעיל על ידי המשתמש.
  • לא יכול להפעיל עבודות/אזעקות או להשתמש ברשת ברקע.
  • לא יכול להפעיל שירותי חזית.
  • ניתן לשנות לאפליקציה ללא הגבלה על ידי המשתמש.

מיישמי מכשירים יכולים להוסיף הגבלות נוספות לאפליקציות כדי:

  • הגבל את האפליקציה מהפעלה מחדש עצמית.
  • הגבל שירותים מלהיות כבולים (מסוכן מאוד).

אפליקציות מוגבלות ברקע לא צפויות לצרוך משאבי מכשיר כלשהם, כגון זיכרון, מעבד וסוללה. אפליקציות עם הגבלת רקע לא אמורות להשפיע על תקינות המכשיר כאשר המשתמש אינו משתמש באפליקציות אלו באופן פעיל. עם זאת, אותן אפליקציות צפויות לפעול באופן מלא כאשר המשתמש מפעיל את האפליקציות.

שימוש ביישומים מותאמים אישית

מיישמי מכשירים יכולים להמשיך להשתמש בשיטות המותאמות אישית שלהם כדי להחיל הגבלות על האפליקציות.

שילוב הגבלות אפליקציות

הסעיפים הבאים מתארים כיצד להגדיר ולשלב הגבלות אפליקציה במכשיר שלך. אם אתה משתמש בשיטות הגבלת אפליקציות מ-Android 8.x ומטה, עיין מקרוב בסעיפים הבאים לגבי שינויים ב-Android 9 ואילך.

הגדרת דגל AppOpsManager

כאשר אפליקציה מוגבלת, הגדר את הדגל המתאים ב- AppOpsManager . קטע קוד לדוגמה מתוך packages/apps/Settings/src/com/android/settings/fuelgauge/BatteryUtils.java :

   public void setForceAppStandby(int uid, String packageName,
            int mode) {
        final boolean isPreOApp = isPreOApp(packageName);
        if (isPreOApp) {
       // Control whether app could run in the background if it is pre O app
            mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName, mode);
        }
       // Control whether app could run jobs in the background
        mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);
    }

הבטחת ש-isBackgroundRestricted מחזירה true

כאשר אפליקציה מוגבלת, ודא ש- ActivityManager.isBackgroundRestricted() מחזירה true .

רישום סיבת ההגבלה

כאשר אפליקציה מוגבלת, רשום את הסיבות להגבלה. קטע קוד לדוגמה של רישום מתוך packages/apps/Settings/src/com/android/settings/fuelgauge/batterytip/actions/RestrictAppAction.java :

mBatteryUtils.setForceAppStandby(mBatteryUtils.getPackageUid(packageName), packageName,AppOpsManager.MODE_IGNORED);
if (CollectionUtils.isEmpty(appInfo.anomalyTypes)) {
  // Only log context if there is no anomaly type
  mMetricsFeatureProvider.action(mContext,
    MetricsProto.MetricsEvent.ACTION_TIP_RESTRICT_APP, packageName,
    Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT,metricsKey));
            } else {
  // Log ALL the anomaly types
  for (int type : appInfo.anomalyTypes) {
    mMetricsFeatureProvider.action(mContext,
      MetricsProto.MetricsEvent.ACTION_TIP_RESTRICT_APP, packageName,
      Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey),
      Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, type));
  }

החלף type בערך מ- AnomalyType .

מיישמי מכשירים יכולים להשתמש בקבועים המוגדרים ב- src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java :

public @interface AnomalyType {
        // This represents an error condition in the anomaly detection.
        int NULL = -1;
         // The anomaly type does not match any other defined type.
        int UNKNOWN_REASON = 0;
         // The application held a partial (screen off) wake lock for a period of time that
         // exceeded the threshold with the screen off when not charging.
        int EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF = 1;
         // The application exceeded the maximum number of wakeups while in the background
         // when not charging.
        int EXCESSIVE_WAKEUPS_IN_BACKGROUND = 2;
         // The application did unoptimized Bluetooth scans too frequently when not charging.
        int EXCESSIVE_UNOPTIMIZED_BLE_SCAN = 3;
         // The application ran in the background for a period of time that exceeded the
         // threshold.
        int EXCESSIVE_BACKGROUND_SERVICE = 4;
         // The application exceeded the maximum number of wifi scans when not charging.
        int EXCESSIVE_WIFI_SCAN = 5;
         // The application exceed the maximum number of flash writes
        int EXCESSIVE_FLASH_WRITES = 6;
         // The application used more than the maximum memory, while not spending any time
         // in the foreground.
        int EXCESSIVE_MEMORY_IN_BACKGROUND = 7;
         // The application exceeded the maximum percentage of frames with a render rate of
         // greater than 700ms.
        int EXCESSIVE_DAVEY_RATE = 8;
         // The application exceeded the maximum percentage of frames with a render rate
         // greater than 16ms.
        int EXCESSIVE_JANKY_FRAMES = 9;
         // The application exceeded the maximum cold start time - the app has not been
         // launched since last system start, died or was killed.
        int SLOW_COLD_START_TIME = 10;
         // The application exceeded the maximum hot start time - the app and activity are
         // already in memory.
        int SLOW_HOT_START_TIME = 11;
         // The application exceeded the maximum warm start time - the app was already in
         // memory but the activity wasn't created yet or was removed from memory.
        int SLOW_WARM_START_TIME = 12;
         // The application exceeded the maximum number of syncs while in the background.
        int EXCESSIVE_BACKGROUND_SYNCS = 13;
         // The application exceeded the maximum number of gps scans while in the background.
        int EXCESSIVE_GPS_SCANS_IN_BACKGROUND = 14;
         // The application scheduled more than the maximum number of jobs while not charging.
        int EXCESSIVE_JOB_SCHEDULING = 15;
         // The application exceeded the maximum amount of mobile network traffic while in
         // the background.
        int EXCESSIVE_MOBILE_NETWORK_IN_BACKGROUND = 16;
         // The application held the WiFi lock for more than the maximum amount of time while
         // not charging.
        int EXCESSIVE_WIFI_LOCK_TIME = 17;
         // The application scheduled a job that ran longer than the maximum amount of time.
        int JOB_TIMED_OUT = 18;
         // The application did an unoptimized Bluetooth scan that exceeded the maximum
         // time while in the background.
        int LONG_UNOPTIMIZED_BLE_SCAN = 19;
         // The application exceeded the maximum ANR rate while in the background.
        int BACKGROUND_ANR = 20;
         // The application exceeded the maximum crash rate while in the background.
        int BACKGROUND_CRASH_RATE = 21;
         // The application exceeded the maximum ANR-looping rate.
        int EXCESSIVE_ANR_LOOPING = 22;
         // The application exceeded the maximum ANR rate.
        int EXCESSIVE_ANRS = 23;
         // The application exceeded the maximum crash rate.
        int EXCESSIVE_CRASH_RATE = 24;
         // The application exceeded the maximum crash-looping rate.
        int EXCESSIVE_CRASH_LOOPING = 25;
         // The application crashed because no more file descriptors were available.
        int NUMBER_OF_OPEN_FILES = 26;
    }

כאשר המשתמש או המערכת מסירים הגבלות של אפליקציה, עליך לרשום את הסיבות להסרת ההגבלות. קטע קוד לדוגמה של רישום מתוך packages/apps/Settings/src/com/android/settings/fuelgauge/batterytip/actions/UnrestrictAppAction.java :

public void handlePositiveAction(int metricsKey) {
        final AppInfo appInfo = mUnRestrictAppTip.getUnrestrictAppInfo();
        // Clear force app standby, then app can run in the background
        mBatteryUtils.setForceAppStandby(appInfo.uid, appInfo.packageName,
                AppOpsManager.MODE_ALLOWED);
        mMetricsFeatureProvider.action(mContext,
                MetricsProto.MetricsEvent.ACTION_TIP_UNRESTRICT_APP, appInfo.packageName,
                Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey));
    }

בדיקת הגבלות אפליקציה

כדי לבדוק את ההתנהגות של הגבלות אפליקציות באנדרואיד 9 ומעלה, השתמש באחת מהפקודות הבאות:

  • הכניסו אפליקציה להגבלה:
    appops set package-name RUN_ANY_IN_BACKGROUND ignore
  • הוצא אפליקציה מהגבלה ושחזר את התנהגות ברירת המחדל:
    appops set package-name RUN_ANY_IN_BACKGROUND allow
  • הפוך אפליקציה ברקע לבטלה מיד:
    am make-uid-idle [--user user-id | all | current] package-name
  • הוסף חבילה לרשימת tempwhitelist למשך זמן קצר:
    cmd deviceidle tempwhitelist [-u user] [-d duration] [package package-name]
  • הוסף/הסר חבילה מרשימת ההיתרים של המשתמש:
    cmd deviceidle whitelist [+/-]package-name
  • בדוק את המצב הפנימי של jobscheduler ומנהל האזעקה:
    dumpsys jobscheduler
    dumpsys alarm

המתנה לאפליקציה

המתנה לאפליקציה מאריכה את חיי הסוללה על ידי דחיית פעילות רשת ברקע ומשרות עבור אפליקציות שהמשתמש אינו משתמש בהן באופן פעיל.

מחזור חיים של המתנה לאפליקציה

הפלטפורמה מזהה אפליקציות לא פעילות ומעמידה אותן במצב המתנה לאפליקציה עד שהמשתמש מתחיל לעסוק באופן פעיל באפליקציה.

במהלך שלב הזיהוי , הפלטפורמה מזהה שאפליקציה אינה פעילה כאשר המכשיר אינו בטעינה והמשתמש לא השיק את האפליקציה באופן ישיר או עקיף במשך כמות מסוימת של זמן שעון כמו גם כמות מסוימת של זמן הפעלת מסך . (השקות עקיפות מתרחשות כאשר אפליקציה בחזית ניגשת לשירות באפליקציה שנייה.)

בזמן המתנה של אפליקציות , הפלטפורמה מונעת מאפליקציות לגשת לרשת יותר מפעם אחת ביום, ודוחה את סנכרון האפליקציות ועבודות אחרות.

הפלטפורמה יוצאת מהאפליקציה מהמתנה כאשר:

  • האפליקציה הופכת להיות פעילה.
  • המכשיר מחובר לחשמל ונטען.

אפליקציות פעילות אינן מושפעות מהמתנה לאפליקציה. אפליקציה פעילה כאשר יש לה:

  • תהליך שנמצא כעת בחזית (כפעילות או כשירות חזית, או בשימוש על ידי פעילות אחרת או שירות חזית), כגון מאזין התראות, שירותי נגישות, טפטים חיים וכו'.
  • הודעה שנצפה על ידי המשתמש, כגון במסך הנעילה או במגש ההתראות
  • הושק במפורש על ידי המשתמש

אפליקציה אינה פעילה אם אף אחת מהפעילויות לעיל לא התרחשה במשך תקופה מסוימת.

בדיקת המתנה של אפליקציה

אתה יכול לבדוק באופן ידני את המתנה של אפליקציה באמצעות פקודות adb הבאות:

adb shell dumpsys battery unplug
adb shell am set-idle package-name true
adb shell am set-idle package-name false
adb shell am get-idle package-name