boolean updateSize(Context context, Debug.MemoryInfo mem, int curSeq) { mSize = ((long) mem.getTotalPss()) * 1024; if (mCurSeq == curSeq) { String sizeStr = Formatter.formatShortFileSize(context, mSize); if (!sizeStr.equals(mSizeStr)) { mSizeStr = sizeStr; // We update this on the second tick where we update just // the text in the current items, so no need to say we // changed here. return false; } } return false; }
/** * Get all running apps 如何判断多个进程是属于一个app? 1. 相同的前缀包名 返回的运行时应用列表, 按照内存占用量降序排序 * * @param ctx * @return */ public List<Map<String, Object>> getRunningApps(Context ctx) { // get all running app processes List<RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses(); if (runningAppProcesses == null) return null; // sort all running app processes Collections.sort( runningAppProcesses, new Comparator<RunningAppProcessInfo>() { @Override public int compare(RunningAppProcessInfo lhs, RunningAppProcessInfo rhs) { String lhsPkgName = lhs.processName.split(":")[0]; String rhsPkgName = rhs.processName.split(":")[0]; return lhsPkgName.compareToIgnoreCase(rhsPkgName); } }); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); ResolveInfo resolveInfo = appHelper.getPm().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); String currentHomePackage = resolveInfo.activityInfo.packageName; IGNORE_PKGS.add(currentHomePackage); // remove all ignored packages Log.i(TAG, "before remove :" + runningAppProcesses.size()); ArrayList<RunningAppProcessInfo> toBeRemoved = new ArrayList<RunningAppProcessInfo>(); for (RunningAppProcessInfo runningProcessInfo : runningAppProcesses) { Log.i(TAG, "after sort:" + runningProcessInfo.processName); try { String appPkgname = runningProcessInfo.processName.split(":")[0]; if (IGNORE_PKGS.contains(appPkgname)) { toBeRemoved.add(runningProcessInfo); } } catch (Exception e) { e.printStackTrace(); Log.w(TAG, "exception raised while remove ignore list:" + e.toString()); } } runningAppProcesses.removeAll(toBeRemoved); Log.i( TAG, "removed :" + toBeRemoved.size() + " ignored packages, after remove size:" + runningAppProcesses.size()); Map<String, Map<String, Object>> runningApps = new HashMap<String, Map<String, Object>>(); // iterate the running app process list for (RunningAppProcessInfo runningProcessInfo : runningAppProcesses) { String[] pkgNameSections = runningProcessInfo.processName.split(":"); Log.i( TAG, "process name:" + runningProcessInfo.processName + ", pkgNameSections length:" + pkgNameSections.length); if (pkgNameSections.length == 0) { // TODO: process name is ""? continue; } String appPkgname = pkgNameSections[0]; String subProcessName = (pkgNameSections.length == 2) ? pkgNameSections[1] : null; Log.i(TAG, "appPkgname:" + appPkgname + ", subProcessName:" + subProcessName); // get application info from package name ApplicationInfo appInfo = appHelper.getApplicationInfo(appPkgname); if (appInfo == null) appInfo = appHelper.getApplicationInfo(runningProcessInfo.processName); // get app info by app package name Map<String, Object> appInfoMap = runningApps.get(appPkgname); if (appInfoMap == null) appInfoMap = new HashMap<String, Object>(); // put app package name if (!appInfoMap.containsKey(PKG_NAME)) { appInfoMap.put(PKG_NAME, appPkgname); } // put app uid if (!appInfoMap.containsKey(APP_UID)) { appInfoMap.put(APP_UID, runningProcessInfo.uid); } // put recommend flag if (!appInfoMap.containsKey(APP_RECOMMEND_CLEAN)) { appInfoMap.put(APP_RECOMMEND_CLEAN, !NOT_RECOMMAND_PKGS.contains(appPkgname)); } // only main process can get human readable name if (appInfo != null) { appInfoMap.put(APP_NAME, appInfo.loadLabel(appHelper.getPm()).toString()); } else if (!appInfoMap.containsKey(APP_NAME)) { appInfoMap.put(APP_NAME, appPkgname); } // get and put app icon if (appInfo != null) { appInfoMap.put(APP_ICON, appInfo.loadIcon(appHelper.getPm())); } else if (!appInfoMap.containsKey(APP_ICON)) { appInfoMap.put(APP_ICON, android.R.drawable.sym_def_app_icon); } // get memory size of app process, store mem info <Key(pid), Value(Debug.MemoryInfo)> SparseArray<Debug.MemoryInfo> memoryInfoArray = (SparseArray<Debug.MemoryInfo>) appInfoMap.get(APP_PROC_MEM); if (memoryInfoArray == null) memoryInfoArray = new SparseArray<Debug.MemoryInfo>(); Debug.MemoryInfo memInfo = getDebugMemoryInfos(new int[] {runningProcessInfo.pid})[0]; memoryInfoArray.put(runningProcessInfo.pid, memInfo); appInfoMap.put(APP_PROC_MEM, memoryInfoArray); // update total int totalPss = 0; if (appInfoMap.containsKey(APP_TOTAL_PSS)) totalPss = (Integer) appInfoMap.get(APP_TOTAL_PSS); totalPss += memInfo.getTotalPss(); appInfoMap.put(APP_TOTAL_PSS, totalPss); // add process in process array List<RunningAppProcessInfo> processes = (ArrayList<RunningAppProcessInfo>) appInfoMap.get(APP_PROCS); if (processes == null) processes = new ArrayList<RunningAppProcessInfo>(); processes.add(runningProcessInfo); appInfoMap.put(APP_PROCS, processes); runningApps.put(appPkgname, appInfoMap); } return sortMap(runningApps); }
@Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mDragging) { if (mAnimationState == ANIMATION_STATE_STARTING) { mAnimationStartTime = SystemClock.uptimeMillis(); mAnimationState = ANIMATION_STATE_RUNNING; } if (mAnimationState == ANIMATION_STATE_RUNNING) { float normalized = (float) (SystemClock.uptimeMillis() - mAnimationStartTime) / mAnimationDuration; if (normalized >= 1.0f) { mAnimationState = ANIMATION_STATE_DONE; } normalized = Math.min(normalized, 1.0f); final float value = mAnimationFrom + (mAnimationTo - mAnimationFrom) * normalized; switch (mAnimationType) { case ANIMATION_TYPE_SCALE: if (mDrawModeBitmap && mDragBitmap != null) { final Bitmap dragBitmap = mDragBitmap; canvas.save(); canvas.translate( getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY); canvas.translate( (dragBitmap.getWidth() * (1.0f - value)) / 2, (dragBitmap.getHeight() * (1.0f - value)) / 2); canvas.scale(value, value); canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint); canvas.restore(); } else { canvas.save(); canvas.translate( getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY); canvas.translate( (mDrawWidth * (1.0f - value)) / 2, (mDrawHeight * (1.0f - value)) / 2); canvas.drawRoundRect( new RectF(0, 0, mDrawWidth, mDrawHeight), 8.0f, 8.0f, mRectPaint); canvas.restore(); } break; } } else { // Draw actual icon being dragged if (mDrawModeBitmap && mDragBitmap != null) { canvas.drawBitmap( mDragBitmap, getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY, mDragPaint); } else { canvas.save(); canvas.translate( getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY); canvas.drawRoundRect(new RectF(0, 0, mDrawWidth, mDrawHeight), 8.0f, 8.0f, mRectPaint); canvas.restore(); } } } if (pids.length > 0 && AlmostNexusSettingsHelper.getDebugShowMemUsage(getContext())) { mRectPaint.setTextSize(debugTextSize); mRectPaint.setAntiAlias(true); mRectPaint.setColor(0xff000000); if (pids.length > 0) canvas.drawRect(0, 0, getWidth(), 70, mRectPaint); mRectPaint.setColor(0xffffffff); memoryInfoArray = activityManager.getProcessMemoryInfo(pids); for (Debug.MemoryInfo pidMemoryInfo : memoryInfoArray) { canvas.drawText( "getTotalPrivateDirty: " + pidMemoryInfo.getTotalPrivateDirty(), 0, debugTextSize, mRectPaint); canvas.drawText( "getTotalPss: " + pidMemoryInfo.getTotalPss(), 0, debugTextSize * 2, mRectPaint); canvas.drawText( "getTotalSharedDirty: " + pidMemoryInfo.getTotalSharedDirty(), 0, debugTextSize * 3, mRectPaint); } } }