+
+ @Override
+ public void onPause() {
+ // Run the default commands.
+ super.onPause();
+
+ // Pause the updating of the memory usage.
+ updateMemoryUsageBoolean = false;
+ }
+
+ @Override
+ public void onResume() {
+ // Run the default commands.
+ super.onResume();
+
+ // Resume the updating of the memory usage.
+ updateMemoryUsageBoolean = true;
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
+ // Run the default commands.
+ super.onSaveInstanceState(savedInstanceState);
+
+ // Save the scroll positions if the tab layout is not null, which can happen if a tab is not currently selected.
+ if (tabLayout != null) {
+ savedInstanceState.putInt("scroll_x", tabLayout.getScrollX());
+ savedInstanceState.putInt("scroll_y", tabLayout.getScrollY());
+ }
+ }
+
+ public void updateMemoryUsage(Activity activity) {
+ try {
+ // Update the memory usage if enabled.
+ if (updateMemoryUsageBoolean) {
+ // Populate the memory info variable.
+ activityManager.getMemoryInfo(memoryInfo);
+
+ // Get the app memory information.
+ long appAvailableMemoryLong = runtime.freeMemory();
+ long appTotalMemoryLong = runtime.totalMemory();
+ long appMaximumMemoryLong = runtime.maxMemory();
+
+ // Calculate the app consumed memory.
+ long appConsumedMemoryLong = appTotalMemoryLong - appAvailableMemoryLong;
+
+ // Get the system memory information.
+ long systemTotalMemoryLong = memoryInfo.totalMem;
+ long systemAvailableMemoryLong = memoryInfo.availMem;
+
+ // Calculate the system consumed memory.
+ long systemConsumedMemoryLong = systemTotalMemoryLong - systemAvailableMemoryLong;
+
+ // Convert the memory information into mebibytes.
+ float appConsumedMemoryFloat = (float) appConsumedMemoryLong / MEBIBYTE;
+ float appAvailableMemoryFloat = (float) appAvailableMemoryLong / MEBIBYTE;
+ float appTotalMemoryFloat = (float) appTotalMemoryLong / MEBIBYTE;
+ float appMaximumMemoryFloat = (float) appMaximumMemoryLong / MEBIBYTE;
+ float systemConsumedMemoryFloat = (float) systemConsumedMemoryLong / MEBIBYTE;
+ float systemAvailableMemoryFloat = (float) systemAvailableMemoryLong / MEBIBYTE;
+ float systemTotalMemoryFloat = (float) systemTotalMemoryLong / MEBIBYTE;
+
+ // Get the mebibyte string.
+ String mebibyte = getString(R.string.mebibyte);
+
+ // Calculate the mebibyte length.
+ int mebibyteLength = mebibyte.length();
+
+ // Create spannable string builders.
+ SpannableStringBuilder appConsumedMemoryStringBuilder = new SpannableStringBuilder(appConsumedMemoryLabel + numberFormat.format(appConsumedMemoryFloat) + " " + mebibyte);
+ SpannableStringBuilder appAvailableMemoryStringBuilder = new SpannableStringBuilder(appAvailableMemoryLabel + numberFormat.format(appAvailableMemoryFloat) + " " + mebibyte);
+ SpannableStringBuilder appTotalMemoryStringBuilder = new SpannableStringBuilder(appTotalMemoryLabel + numberFormat.format(appTotalMemoryFloat) + " " + mebibyte);
+ SpannableStringBuilder appMaximumMemoryStringBuilder = new SpannableStringBuilder(appMaximumMemoryLabel + numberFormat.format(appMaximumMemoryFloat) + " " + mebibyte);
+ SpannableStringBuilder systemConsumedMemoryStringBuilder = new SpannableStringBuilder(systemConsumedMemoryLabel + numberFormat.format(systemConsumedMemoryFloat) + " " + mebibyte);
+ SpannableStringBuilder systemAvailableMemoryStringBuilder = new SpannableStringBuilder(systemAvailableMemoryLabel + numberFormat.format(systemAvailableMemoryFloat) + " " + mebibyte);
+ SpannableStringBuilder systemTotalMemoryStringBuilder = new SpannableStringBuilder(systemTotalMemoryLabel + numberFormat.format(systemTotalMemoryFloat) + " " + mebibyte);
+
+ // Setup the spans to display the memory information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ appConsumedMemoryStringBuilder.setSpan(blueColorSpan, appConsumedMemoryLabel.length(), appConsumedMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ appAvailableMemoryStringBuilder.setSpan(blueColorSpan, appAvailableMemoryLabel.length(), appAvailableMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ appTotalMemoryStringBuilder.setSpan(blueColorSpan, appTotalMemoryLabel.length(), appTotalMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ appMaximumMemoryStringBuilder.setSpan(blueColorSpan, appMaximumMemoryLabel.length(), appMaximumMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ systemConsumedMemoryStringBuilder.setSpan(blueColorSpan, systemConsumedMemoryLabel.length(), systemConsumedMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ systemAvailableMemoryStringBuilder.setSpan(blueColorSpan, systemAvailableMemoryLabel.length(), systemAvailableMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ systemTotalMemoryStringBuilder.setSpan(blueColorSpan, systemTotalMemoryLabel.length(), systemTotalMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ // Display the string in the text boxes.
+ appConsumedMemoryTextView.setText(appConsumedMemoryStringBuilder);
+ appAvailableMemoryTextView.setText(appAvailableMemoryStringBuilder);
+ appTotalMemoryTextView.setText(appTotalMemoryStringBuilder);
+ appMaximumMemoryTextView.setText(appMaximumMemoryStringBuilder);
+ systemConsumedMemoryTextView.setText(systemConsumedMemoryStringBuilder);
+ systemAvailableMemoryTextView.setText(systemAvailableMemoryStringBuilder);
+ systemTotalMemoryTextView.setText(systemTotalMemoryStringBuilder);
+ }
+
+ // Schedule another memory update if the activity has not been destroyed.
+ if (!activity.isDestroyed()) {
+ // Create a handler to update the memory usage.
+ Handler updateMemoryUsageHandler = new Handler();
+
+ // Create a runnable to update the memory usage.
+ Runnable updateMemoryUsageRunnable = () -> updateMemoryUsage(activity);
+
+ // Update the memory usage after 1000 milliseconds
+ updateMemoryUsageHandler.postDelayed(updateMemoryUsageRunnable, 1000);
+ }
+ } catch (Exception exception) {
+ // Do nothing.
+ }
+ }