Skip to content

Commit

Permalink
[RunningApps] Auto-refresh apps in every 10 seconds
Browse files Browse the repository at this point in the history
Signed-off-by: Muntashir Al-Islam <[email protected]>
  • Loading branch information
MuntashirAkon committed Mar 26, 2024
1 parent c527baa commit 4595100
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,6 @@ public AppProcessItem[] newArray(int size) {
}
};

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AppProcessItem)) {
if (o instanceof ProcessItem) {
return super.equals(o);
}
return false;
}
if (!super.equals(o)) return false;
AppProcessItem that = (AppProcessItem) o;
return packageInfo.equals(that.packageInfo);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), packageInfo);
}

@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

package io.github.muntashirakon.AppManager.runningapps;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Process;
import android.text.TextUtils;
Expand All @@ -29,6 +26,8 @@
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import io.github.muntashirakon.AppManager.BaseActivity;
import io.github.muntashirakon.AppManager.R;
Expand All @@ -44,14 +43,13 @@
import io.github.muntashirakon.AppManager.settings.FeatureController;
import io.github.muntashirakon.AppManager.settings.Ops;
import io.github.muntashirakon.AppManager.settings.Prefs;
import io.github.muntashirakon.AppManager.utils.ThreadUtils;
import io.github.muntashirakon.AppManager.utils.UIUtils;
import io.github.muntashirakon.multiselection.MultiSelectionActionsView;
import io.github.muntashirakon.widget.MultiSelectionView;
import io.github.muntashirakon.widget.SwipeRefreshLayout;

public class RunningAppsActivity extends BaseActivity implements MultiSelectionView.OnSelectionChangeListener,
MultiSelectionActionsView.OnItemSelectedListener, AdvancedSearchView.OnQueryTextListener,
SwipeRefreshLayout.OnRefreshListener {
MultiSelectionActionsView.OnItemSelectedListener, AdvancedSearchView.OnQueryTextListener {

@IntDef(value = {
SORT_BY_PID,
Expand Down Expand Up @@ -97,18 +95,10 @@ public class RunningAppsActivity extends BaseActivity implements MultiSelectionV
@Nullable
private LinearProgressIndicator mProgressIndicator;
@Nullable
private SwipeRefreshLayout mSwipeRefresh;
@Nullable
private MultiSelectionView mMultiSelectionView;
@Nullable
private Menu mSelectionMenu;

private final BroadcastReceiver mBatchOpsBroadCastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
refresh();
}
};
private Timer mTimer;

@Override
protected void onAuthenticated(Bundle savedInstanceState) {
Expand All @@ -122,12 +112,10 @@ protected void onAuthenticated(Bundle savedInstanceState) {
model = new ViewModelProvider(this).get(RunningAppsViewModel.class);
mProgressIndicator = findViewById(R.id.progress_linear);
mProgressIndicator.setVisibilityAfterHide(View.GONE);
mSwipeRefresh = findViewById(R.id.swipe_refresh);
mSwipeRefresh.setOnRefreshListener(this);
RecyclerView recyclerView = findViewById(R.id.scrollView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new RunningAppsAdapter(this);
mAdapter.setHasStableIds(true);
mAdapter.setHasStableIds(false);
recyclerView.setAdapter(mAdapter);
// Recycler view is focused by default
recyclerView.requestFocus();
Expand All @@ -149,9 +137,11 @@ protected void onAuthenticated(Bundle savedInstanceState) {
}
});
model.observeKillSelectedProcess().observe(this, processInfoList -> {
if (processInfoList.size() != 0) {
if (!processInfoList.isEmpty()) {
List<String> processNames = new ArrayList<String>() {{
for (ProcessItem processItem : processInfoList) add(processItem.name);
for (ProcessItem processItem : processInfoList) {
add(processItem.name);
}
}};
UIUtils.displayLongToast(R.string.failed_to_stop, TextUtils.join(", ", processNames));
}
Expand Down Expand Up @@ -264,9 +254,6 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
mEnableKillForSystem = !mEnableKillForSystem;
Prefs.RunningApps.setEnableKillForSystemApps(mEnableKillForSystem);
refresh();
} else if (id == R.id.action_refresh) {
refresh();
// Sort
} else if (id == R.id.action_sort_by_pid) {
model.setSortOrder(SORT_BY_PID);
item.setChecked(true);
Expand Down Expand Up @@ -295,23 +282,25 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
@Override
protected void onResume() {
super.onResume();
refresh();
ContextCompat.registerReceiver(this, mBatchOpsBroadCastReceiver,
new IntentFilter(BatchOpsService.ACTION_BATCH_OPS_COMPLETED), ContextCompat.RECEIVER_NOT_EXPORTED);
mTimer = new Timer("running_apps");
mTimer.schedule(new TimerTask() {
@Override
public void run() {
ThreadUtils.postOnMainThread(() -> {
if (model != null) {
model.loadProcesses();
model.loadMemoryInfo();
}
});
}
}, 0, 10_000);
}

@Override
protected void onPause() {
mTimer.cancel();
mTimer.purge();
super.onPause();
unregisterReceiver(mBatchOpsBroadCastReceiver);
}

@Override
public void onRefresh() {
if (mSwipeRefresh != null) {
mSwipeRefresh.setRefreshing(false);
}
refresh();
}

@Override
Expand Down Expand Up @@ -381,7 +370,7 @@ public boolean onSelectionChange(int selectionCount) {
}
}
}
kill.setEnabled(selectedItems.size() != 0 && killEnabled);
kill.setEnabled(!selectedItems.isEmpty() && killEnabled);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public class RunningAppsAdapter extends MultiSelectionView.Adapter<MultiSelectio

void setDefaultList(@NonNull List<ProcessItem> processItems) {
synchronized (mLock) {
int previousCount = mProcessItems.size();
int previousCount = mProcessItems.size() + 1;
mProcessItems = processItems;
AdapterUtils.notifyDataSetChanged(this, previousCount, mProcessItems.size());
AdapterUtils.notifyDataSetChanged(this, previousCount, mProcessItems.size() + 1);
}
notifySelectionChange();
}
Expand Down Expand Up @@ -120,13 +120,10 @@ private void onBindViewHolder(@NonNull HeaderViewHolder holder) {
long buffers = mProcMemoryInfo.getBuffers();
long freeMemory = mProcMemoryInfo.getFreeMemory();
double total = appMemory + cachedMemory + buffers + freeMemory;
if (total == 0) {
// Error due to parsing failure, etc.
holder.mMemoryInfoChart.setVisibility(View.GONE);
holder.mMemoryShortInfoView.setVisibility(View.GONE);
holder.mMemoryInfoView.setVisibility(View.GONE);
return;
}
boolean totalIsNonZero = total > 0;
AdapterUtils.setVisible(holder.mMemoryInfoChart, totalIsNonZero);
AdapterUtils.setVisible(holder.mMemoryShortInfoView, totalIsNonZero);
AdapterUtils.setVisible(holder.mMemoryInfoView, totalIsNonZero);
holder.mMemoryInfoChart.post(() -> {
int width = holder.mMemoryInfoChart.getWidth();
setLayoutWidth(holder.mMemoryInfoChartChildren[0], (int) (width * appMemory / total));
Expand All @@ -147,13 +144,10 @@ private void onBindViewHolder(@NonNull HeaderViewHolder holder) {
// Swap
long usedSwap = mProcMemoryInfo.getUsedSwap();
long totalSwap = mProcMemoryInfo.getTotalSwap();
if (totalSwap == 0) {
holder.mSwapInfoChart.setVisibility(View.GONE);
holder.mSwapShortInfoView.setVisibility(View.GONE);
holder.mSwapInfoView.setVisibility(View.GONE);
// No swap
return;
}
boolean totalSwapIsNonZero = totalSwap > 0;
AdapterUtils.setVisible(holder.mSwapInfoChart, totalSwapIsNonZero);
AdapterUtils.setVisible(holder.mSwapShortInfoView, totalSwapIsNonZero);
AdapterUtils.setVisible(holder.mSwapInfoView, totalSwapIsNonZero);
holder.mSwapInfoChart.post(() -> {
int width = holder.mSwapInfoChart.getWidth();
setLayoutWidth(holder.mSwapInfoChartChildren[0], (int) (width * usedSwap / totalSwap));
Expand Down Expand Up @@ -183,10 +177,10 @@ private void onBindViewHolder(@NonNull BodyViewHolder holder, int position) {
// Set process name
holder.processName.setText(UIUtils.getHighlightedText(processName, mModel.getQuery(), mQueryStringHighlightColor));
// Set package name
AdapterUtils.setVisible(holder.packageName, applicationInfo != null);
if (applicationInfo != null) {
holder.packageName.setVisibility(View.VISIBLE);
holder.packageName.setText(UIUtils.getHighlightedText(applicationInfo.packageName, mModel.getQuery(), mQueryStringHighlightColor));
} else holder.packageName.setVisibility(View.GONE);
}
// Set process IDs
holder.processIds.setText(mActivity.getString(R.string.pid_and_ppid, processItem.pid, processItem.ppid));
// Set memory usage
Expand Down Expand Up @@ -275,7 +269,7 @@ private void onBindViewHolder(@NonNull BodyViewHolder holder, int position) {
int lastSelectedItemPosition = lastSelectedItem == null ? -1 : mProcessItems.indexOf(lastSelectedItem);
if (lastSelectedItemPosition >= 0) {
// Select from last selection to this selection
selectRange(lastSelectedItemPosition, position);
selectRange(lastSelectedItemPosition + 1, position);
} else toggleSelection(position);
return true;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ public void filterAndSort() {

private final Set<ProcessItem> mSelectedItems = new LinkedHashSet<>();

@Nullable
public ProcessItem getLastSelectedItem() {
// Last selected package is the same as the last added package.
Iterator<ProcessItem> it = mSelectedItems.iterator();
Expand Down
24 changes: 8 additions & 16 deletions app/src/main/res/layout/activity_running_apps.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,17 @@

<include layout="@layout/appbar" />

<io.github.muntashirakon.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
<io.github.muntashirakon.widget.RecyclerView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

<io.github.muntashirakon.widget.RecyclerView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:scrollbars="none"
android:fitsSystemWindows="true"
android:clipToPadding="false"
app:fastScrollerEnabled="true"
tools:listitem="@layout/item_running_app" />

</io.github.muntashirakon.widget.SwipeRefreshLayout>
android:scrollbars="none"
android:fitsSystemWindows="true"
android:clipToPadding="false"
app:fastScrollerEnabled="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
tools:listitem="@layout/item_running_app" />

<io.github.muntashirakon.widget.MultiSelectionView
android:id="@+id/selection_view"
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/menu/activity_running_apps_actions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,4 @@
app:showAsAction="never"
android:title="@string/toggle_kill_for_system_apps" />

<item
android:id="@+id/action_refresh"
android:icon="@drawable/ic_refresh"
android:title="@string/refresh"
app:showAsAction="never" />

</menu>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package io.github.muntashirakon.util;

import android.os.Looper;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -46,4 +47,12 @@ public static void notifyDataSetChanged(@NonNull RecyclerView.Adapter<?> adapter
adapter.notifyItemRangeChanged(0, previousCount);
}
}

public static void setVisible(@NonNull View v, boolean visible) {
if (visible && v.getVisibility() != View.VISIBLE) {
v.setVisibility(View.VISIBLE);
} else if (!visible && v.getVisibility() != View.GONE) {
v.setVisibility(View.GONE);
}
}
}

0 comments on commit 4595100

Please sign in to comment.