activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity"
android:background="#005eff"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<Button
android:id="@+id/btn_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:background="#90b990"
/>
<Button
android:id="@+id/btn_kill"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kill"
android:layout_above="@id/btn_refresh"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:background="#789f7b"
/>
</RelativeLayout>
custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp"
card_view:contentPadding="5dp"
android:clickable="false"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cbd7f1"
android:layout_margin="2dp"
android:padding="5dp"
android:clickable="false"
>
<TextView
android:id="@+id/tv_process_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
/>
<TextView
android:id="@+id/tv_package_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:clickable="false"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
MainActivity.java
package com.cfsuman.me.androidcode;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Context mContext;
private Button mButtonRefresh;
private Button mButtonKill;
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
// Request window feature action bar
requestWindowFeature(Window.FEATURE_ACTION_BAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the application context
mContext = getApplicationContext();
// Set the action bar color
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.RED));
// Get the widgets reference from XML layout
mButtonRefresh = (Button) findViewById(R.id.btn_refresh);
mButtonKill = (Button) findViewById(R.id.btn_kill);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
// Use a linear layout manager
mLayoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(mLayoutManager);
// Specify an adapter for RecyclerView
mAdapter = new RecyclerAdapter(getDataSet(),mContext);
mRecyclerView.setAdapter(mAdapter);
// Set a click listener for refresh button widget
mButtonRefresh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Regenerate the adapter for RecyclerView
mAdapter = new RecyclerAdapter(getDataSet(),mContext);
mRecyclerView.setAdapter(mAdapter);
// Show the number of running processes
Toast.makeText(mContext, "Running processes : "
+ mAdapter.getItemCount(), Toast.LENGTH_SHORT).show();
}
});
// Set a click listener for kill button widget
mButtonKill.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Kill the background processes
new KillBackgroundProcessesTask().execute();
}
});
}
// Custom method to generate data set
protected ActivityManager.RunningAppProcessInfo[] getDataSet(){
/*
ActivityManager
Interact with the overall activities running in the system.
*/
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
/*
public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses ()
Returns a list of application processes that are running on the device.
Note: this method is only intended for debugging or building a user-facing
process management UI.
Returns
Returns a list of RunningAppProcessInfo records, or null if there are no running
processes (it will not return an empty list). This list ordering is not specified.
*/
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfoList = am.getRunningAppProcesses();
ActivityManager.RunningAppProcessInfo[] array = runningAppProcessInfoList.toArray(
new ActivityManager.RunningAppProcessInfo[runningAppProcessInfoList.size()]
);
return array;
}
// AsyncTask to kill background processes
private class KillBackgroundProcessesTask extends AsyncTask<Void,Integer,Integer>{
@Override
protected Integer doInBackground(Void...Void){
// Get an instance of PackageManager
PackageManager pm = getPackageManager();
// Get an instance of ActivityManager
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
// Get a list of RunningAppProcessInfo
List<ActivityManager.RunningAppProcessInfo> list = am.getRunningAppProcesses();
// Count the number of running processes
int initialRunningProcessesSize = list.size();
// Iterate over the RunningAppProcess list
for(ActivityManager.RunningAppProcessInfo process: list){
// Ignore, if the process contains package list is empty
if(process.pkgList.length == 0) continue;
try{
// Get the PackageInfo for current process
PackageInfo packageInfo = pm.getPackageInfo(process.pkgList[0],PackageManager.GET_ACTIVITIES);
// Ignore the self app package
if(!packageInfo.packageName.equals(mContext.getPackageName())){
// Try to kill other background processes
// System processes are ignored
am.killBackgroundProcesses(packageInfo.packageName);
}
}catch(PackageManager.NameNotFoundException e){
// Catch the exception
e.printStackTrace();
}
}
// Get the running processes after killing some
int currentRunningProcessesSize = am.getRunningAppProcesses().size();
// Return the number of killed processes
return initialRunningProcessesSize - currentRunningProcessesSize;
}
protected void onPostExecute(Integer result){
// Show the number of killed processes
Toast.makeText(mContext,"Killed : " + result + " processes",Toast.LENGTH_SHORT).show();
}
}
}
RecyclerAdapter.java
package com.cfsuman.me.androidcode;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private ActivityManager.RunningAppProcessInfo[] mDataset;
private Context mContext;
// Provide a reference to the views for each data item
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView mTVProcessName;
public TextView mTVPackageList;
public ViewHolder(View v){
super(v);
mTVProcessName = (TextView) v.findViewById(R.id.tv_process_name);
mTVPackageList = (TextView) v.findViewById(R.id.tv_package_list);
}
}
// Provide a suitable constructor
public RecyclerAdapter(ActivityManager.RunningAppProcessInfo[] myDataset,Context context){
mDataset = myDataset;
mContext = context;
}
// Create new views
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
// Create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_layout,parent,false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position){
// Get element from data set at this position
// Replace the contents of the view with that element
String processString = "<b><u>"+mDataset[position].processName + "</u></b> ";
processString += "<i>(" + getProcessImportance(mDataset[position].importance).toLowerCase()+")</i>";
holder.mTVProcessName.setText(Html.fromHtml(processString));
// By default android takes the package name as the process name.
holder.mTVPackageList.setText("");
String[] packages = mDataset[position].pkgList;
StringBuilder builder = new StringBuilder();
for (int i=0;i<packages.length;i++){
// Get the application name
builder.append("<b>" + getApplicationName(packages[i])+"</b><br/>");
// Determine is it a system application or not
if(isSystemApplication(packages[i])){
builder.append("<i>System app.</i><br/>");
}
// Append the package name
builder.append(packages[i] + "<br/>");
// Show the formatted string in CardView
holder.mTVPackageList.setText(Html.fromHtml(builder.toString()));
}
}
// Return the size of data set
@Override
public int getItemCount(){
return mDataset.length;
}
// Custom method to get process importance
protected String getProcessImportance(int importance){
String processImportance = "";
/*
The relative importance level that the system places on this process. May be one of
IMPORTANCE_FOREGROUND,
IMPORTANCE_VISIBLE,
IMPORTANCE_SERVICE,
IMPORTANCE_BACKGROUND,
IMPORTANCE_EMPTY.
These constants are numbered so that "more important" values are always smaller
than "less important" values.
*/
if(importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND){
processImportance = "BACKGROUND";
}else if (importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY){
processImportance = "EMPTY";
}else if(importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
processImportance = "FOREGROUND";
}else if (importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE){
processImportance = "FOREGROUND SERVICE";
}else if (importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE){
processImportance = "GONE";
}else if (importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE){
processImportance = "PERCEPTIBLE";
}else if(importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE){
processImportance = "SERVICE";
}else if(importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_TOP_SLEEPING){
processImportance = "TOP SLEEPING";
}else if(importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE){
processImportance = "VISIBLE";
}
return processImportance;
}
// Custom method to get application label from package name
protected String getApplicationName(String packageName){
String applicationName = "";
PackageManager pm = mContext.getPackageManager();
ApplicationInfo ai;
try{
ai = pm.getApplicationInfo(packageName,0);
}catch(PackageManager.NameNotFoundException e){
e.printStackTrace();;
ai = null;
}
applicationName = (String)(ai!=null ? pm.getApplicationLabel(ai) : "(UNKNOWN)");
return applicationName;
}
// Custom method to determine an application (package) is system package
protected boolean isSystemApplication(String packageName){
boolean isSystemApp = false;
PackageManager pm = mContext.getPackageManager();
ApplicationInfo ai;
try{
ai = pm.getApplicationInfo(packageName,0);
}catch(PackageManager.NameNotFoundException e){
e.printStackTrace();;
ai = null;
}
if(ai!=null & ai.flags == ApplicationInfo.FLAG_SYSTEM){
isSystemApp = true;
}
return isSystemApp;
}
}
AndroidManifes.xml [permission]
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
build.gradle [dependencies]
compile 'com.android.support:recyclerview-v7:23.0.1'
compile 'com.android.support:cardview-v7:23.0.1'

