How to use ActivityManager.setWatchHeapLimit() to watch heap_limit

240 views Asked by At

According to the official document: https://developer.android.com/reference/android/app/ActivityManager.html#setWatchHeapLimit(long)

I wrote a demo to see whether the HEAP_LIMIT would be triggered.But seems that it was not working,and here is my code.

public class ActivityManagerActivity extends Activity
{

    private String TAG = this.getClass().getName();

    private Button btnIncreaseMemory;
    private BroadcastReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_manager);
        registerBroadcast();
        registerHeapLimit();
        iniComponent();
    }

    private void iniComponent()
    {
        btnIncreaseMemory = (Button) findViewById(R.id.btnIncreaseMemory);
        btnIncreaseMemory.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.image)).getBitmap();
                Log.e(TAG, "bitmap size:" + bitmap.getByteCount());
                ((ImageView) findViewById(R.id.ivBitmap)).setImageBitmap(bitmap);
            }
        });
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        activityManager.clearWatchHeapLimit();

        if (receiver != null)
        {
            unregisterReceiver(receiver);
            receiver = null;
        }
    }

    private void registerHeapLimit()
    {
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        activityManager.setWatchHeapLimit(2);
    }

    private void registerBroadcast()
    {
        IntentFilter filter = new IntentFilter();
        filter.addAction("ACTION_REPORT_HEAP_LIMIT");
        receiver = new BroadcastReceiver()
        {
            @Override
            public void onReceive(Context context, Intent intent)
            {
                // not be called
                Toast.makeText(ActivityManagerActivity.this, "get msg", Toast.LENGTH_SHORT).show();
            }
        };
        registerReceiver(receiver, filter);
    }
}

I change the code to:

public class ActivityManagerActivity extends Activity
{

    private String TAG = this.getClass().getName();

    private Button btnIncreaseMemory;
    private BroadcastReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_manager);
        registerBroadcast();
        registerHeapLimit();
        iniComponent();
    }

    int index = 0;

    private void iniComponent()
    {
        btnIncreaseMemory = (Button) findViewById(R.id.btnIncreaseMemory);
        btnIncreaseMemory.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                if(index == 0)
                {
                    Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.img6802)).getBitmap();
                    Log.e(TAG, "bitmap1 size:" + bitmap.getByteCount());
                    ((ImageView) findViewById(R.id.ivBitmap)).setImageBitmap(bitmap);
                    index = 1;
                }
                else if(index == 1)
                {
                    Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.img6803)).getBitmap();
                    Log.e(TAG, "bitmap2 size:" + bitmap.getByteCount());
                    ((ImageView) findViewById(R.id.ivBitmap2)).setImageBitmap(bitmap);
                    index = 2;
                }
                else if(index == 2)
                {
                    Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.img6804)).getBitmap();
                    Log.e(TAG, "bitmap3 size:" + bitmap.getByteCount());
                    ((ImageView) findViewById(R.id.ivBitmap3)).setImageBitmap(bitmap);
                    index = 3;
                }
            }
        });
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        activityManager.clearWatchHeapLimit();

        if (receiver != null)
        {
            unregisterReceiver(receiver);
            receiver = null;
        }
    }

    private void registerHeapLimit()
    {
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        activityManager.setWatchHeapLimit(157286400);//150MB
    }

    private void registerBroadcast()
    {
        IntentFilter filter = new IntentFilter();
        filter.addAction("ACTION_REPORT_HEAP_LIMIT");
        receiver = new BroadcastReceiver()
        {
            @Override
            public void onReceive(Context context, Intent intent)
            {
                // not be called
                Toast.makeText(ActivityManagerActivity.this, "get msg", Toast.LENGTH_SHORT).show();
            }
        };
        registerReceiver(receiver, filter);
    }
}

But still no notifies, even the used-heap passed the limit 150MB which I set.

1

There are 1 answers

0
kdehairy On

Increase the pss limit to a reasonable value that will be crossed when clicking the button.

The value you provided (2k) is too small, and I believe your activity crosses this value even before you click the button.