android通过广播打印ram使用信息

在内存非常吃紧的情况下,android设备会开始kill部分非系统进程甚至系统进程来保证基本的系统运行。在这种情况下如何获取设备过去某段时间的ram使用情况至关重要。

通过开发者模式中的"内存"可以完美得知设备内存使用信息。

我们可以通过此途径,设计一套通过广播打印内存信息的方式以应对各种调试情况,此文仅将内存信息通过log的形式后台打印获取。

1.发送的广播需要在BroadcastQueue.java特别处理,避免被系统拦截。

2.为了避免各种权限问题,将此套方案耦合在Settings模组。

3.RamInfo参考开发者模式中的方式获取过去某段时间的内存使用情况。

java 复制代码
Index: frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
===================================================================
--- frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java	(版本 10810)
+++ frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java	(版本 10827)
@@ -121,6 +121,7 @@
+        sBackgroundActionWhiteListArraySet.add("com.android.settings.action.RAM_INFO");
     }
 
Index: packages/apps/Settings/src/com/android/settings/applications/RamInfo.java
===================================================================
--- packages/apps/Settings/src/com/android/settings/applications/RamInfo.java	(不存在的)
+++ packages/apps/Settings/src/com/android/settings/applications/RamInfo.java	(版本 10827)
@@ -0,0 +1,120 @@
+package com.android.settings.applications;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.text.format.Formatter;
+import android.text.format.Formatter.BytesResult;
+import android.util.Log;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.applications.ProcStatsData.MemInfo;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class RamInfo extends BroadcastReceiver {
+
+    private static String TAG ="RamInfo";
+
+    private PackageManager mPm;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.d(TAG, "onReceive:" + intent.getAction());
+
+        int index = intent.getIntExtra("index", 3); // 0 - 3h, 1 - 6h, 2 - 12h, 3 - 24h
+
+        mPm = context.getPackageManager();
+
+        ProcStatsData statsManager = new ProcStatsData(context, false);
+        statsManager.setDuration(ProcessStatsBase.sDurations[index]);
+
+        MemInfo memInfo = statsManager.getMemInfo();
+        double usedRam = memInfo.realUsedRam;
+        double totalRam = memInfo.realTotalRam;
+        double freeRam = memInfo.realFreeRam;
+        BytesResult usedResult = Formatter.formatBytes(context.getResources(), (long) usedRam,
+                Formatter.FLAG_SHORTER);
+        String totalString = Formatter.formatShortFileSize(context, (long) totalRam);
+        String freeString = Formatter.formatShortFileSize(context, (long) freeRam);
+        CharSequence memString;
+        CharSequence[] memStatesStr = context.getResources().getTextArray(R.array.ram_states);
+        int memState = statsManager.getMemState();
+        if (memState >= 0 && memState < memStatesStr.length - 1) {
+            memString = memStatesStr[memState];
+        } else {
+            memString = memStatesStr[memStatesStr.length - 1];
+        }
+        String durationString = context.getResources().getString(ProcessStatsBase.sDurationLabels[index]);
+        int numApps = statsManager.getEntries().size();
+
+        Log.d(TAG, "********** RAM INFO (" + durationString + ") **********");
+        // Average
+        Log.d(TAG, context.getResources().getString(R.string.memory_avg_use) + ": " + usedResult.value + usedResult.units);
+        // Performance
+        Log.d(TAG, context.getResources().getString(R.string.memory_performance) + ": " + memString);
+        // Total memory
+        Log.d(TAG, context.getResources().getString(R.string.total_memory) + ": " + totalString);
+        // Average used
+        Log.d(TAG, context.getResources().getString(R.string.average_used) + ": " + (Utils.formatPercentage((long) usedRam, (long) totalRam)));
+        // Free
+        Log.d(TAG, context.getResources().getString(R.string.free_memory) + ": " + freeString);
+        // Memory used by apps
+        Log.d(TAG, context.getResources().getString(R.string.memory_usage_apps)+ ": " + context.getResources().getQuantityString(
+                R.plurals.memory_usage_apps_summary, numApps, numApps, durationString));
+
+        boolean mShowMax = false;
+
+        List<ProcStatsPackageEntry> pkgEntries = statsManager.getEntries();
+
+        // Update everything and get the absolute maximum of memory usage for scaling.
+        for (int i = 0, N = pkgEntries.size(); i < N; i++) {
+            ProcStatsPackageEntry pkg = pkgEntries.get(i);
+            pkg.updateMetrics();
+        }
+
+        Collections.sort(pkgEntries, mShowMax ? sMaxPackageEntryCompare : sPackageEntryCompare);
+
+        for (int i = 0; i < pkgEntries.size(); i++) {
+            ProcStatsPackageEntry pkg = pkgEntries.get(i);
+            pkg.retrieveUiData(context, mPm);
+            boolean statsForeground = pkg.mRunWeight > pkg.mBgWeight;
+            double avgAmount = (statsForeground ? pkg.mRunWeight : pkg.mBgWeight) * memInfo.weightToRam;
+            double maxAmount = (statsForeground ? pkg.mMaxRunMem : pkg.mMaxBgMem) * memInfo.totalScale * 1024;
+            Log.d(TAG, pkg.mUiLabel + "(" + pkg.mPackage + ")" + 
+                    " {" + context.getResources().getString(R.string.memory_avg_use) + ":" + Formatter.formatShortFileSize(context, (long) avgAmount) + " " +
+                    context.getResources().getString(R.string.memory_max_use) + ":" + Formatter.formatShortFileSize(context, (long) maxAmount) + "}");
+        }
+        Log.d(TAG, "********** RAM INFO END **********");
+    }
+
+    final static Comparator<ProcStatsPackageEntry> sPackageEntryCompare
+            = new Comparator<ProcStatsPackageEntry>() {
+        @Override
+        public int compare(ProcStatsPackageEntry lhs, ProcStatsPackageEntry rhs) {
+            double rhsWeight = Math.max(rhs.mRunWeight, rhs.mBgWeight);
+            double lhsWeight = Math.max(lhs.mRunWeight, lhs.mBgWeight);
+            if (lhsWeight == rhsWeight) {
+                return 0;
+            }
+            return lhsWeight < rhsWeight ? 1 : -1;
+        }
+    };
+
+    final static Comparator<ProcStatsPackageEntry> sMaxPackageEntryCompare
+            = new Comparator<ProcStatsPackageEntry>() {
+        @Override
+        public int compare(ProcStatsPackageEntry lhs, ProcStatsPackageEntry rhs) {
+            double rhsMax = Math.max(rhs.mMaxBgMem, rhs.mMaxRunMem);
+            double lhsMax = Math.max(lhs.mMaxBgMem, lhs.mMaxRunMem);
+            if (lhsMax == rhsMax) {
+                return 0;
+            }
+            return lhsMax < rhsMax ? 1 : -1;
+        }
+    };
+}
\ No newline at end of file
Index: packages/apps/Settings/AndroidManifest.xml
===================================================================
--- packages/apps/Settings/AndroidManifest.xml	(版本 10810)
+++ packages/apps/Settings/AndroidManifest.xml	(版本 10827)
@@ -3603,5 +3603,11 @@
             </intent-filter>
         </receiver> 
+
+        <receiver android:name=".applications.RamInfo">
+            <intent-filter>    
+                <action android:name="com.android.settings.action.RAM_INFO" />
+            </intent-filter>
+        </receiver> 
     </application>
 </manifest>
相关推荐
zhangphil25 分钟前
Android ValueAnimator ImageView animate() rotation,Kotlin
android·kotlin
徊忆羽菲1 小时前
CentOS7使用源码安装PHP8教程整理
android
编程、小哥哥2 小时前
python操作mysql
android·python
Couvrir洪荒猛兽2 小时前
Android实训十 数据存储和访问
android
五味香5 小时前
Java学习,List 元素替换
android·java·开发语言·python·学习·golang·kotlin
十二测试录5 小时前
【自动化测试】—— Appium使用保姆教程
android·经验分享·测试工具·程序人生·adb·appium·自动化
Couvrir洪荒猛兽7 小时前
Android实训九 数据存储和访问
android
aloneboyooo7 小时前
Android Studio安装配置
android·ide·android studio
Jacob程序员7 小时前
leaflet绘制室内平面图
android·开发语言·javascript
2401_897907868 小时前
10天学会flutter DAY2 玩转dart 类
android·flutter