Android not killing activities from stack when memory is low

后端 未结 5 1472
旧时难觅i
旧时难觅i 2021-01-02 10:10

We\'ve been developing an application that has a drop down dashboard that allows the users to navigate throughout the app. The navigation is not very standard since this men

相关标签:
5条回答
  • 2021-01-02 10:13

    Calling finish() when you are starting the new activity will deallocate the one you are leaving. This will prevent you from accessing it with the back button, but it should keep memory down.

    0 讨论(0)
  • 2021-01-02 10:18

    I was expecting the system to kill the oldest activities in the stack automatically BEFRORE the OutOfMemoryError was thrown

    Android does not do this. Android terminates processes to free up system memory for other processes. It does not get involved with intra-app memory usage in a similar fashion.

    How can we tell the Android OS that it is allowed to deallocate activities and its resources if needed so we don't get the "Unfortunately, your activity has stopped." dialog?

    You can't.

    Instead, you need to design your application to use fewer activities, or use fewer resources per activity. For example, you can "recycle" existing activity instances via FLAG_ACTIVITY_REORDER_TO_FRONT, or (as Mr. Tornquist pointed out), you can finish() activities manually yourself.

    After playing for a while opening activities using the menu, the stack starts to grow and grow.

    You should probably be using FLAG_ACTIVITY_REORDER_TO_FRONT on these menu items, so that you bring the existing activity forward in the task, rather than creating new ones each time.

    0 讨论(0)
  • 2021-01-02 10:25

    CommonsWare's answer is correct, besides you can try this strategy to release the memory of the activity at the bottom stack:

    • Remove alls fragment and/or setContentView(null)
    • onResume: call Activity#recreate(), or just simply create new fragment instance and add it back to your view hierarchy.

    One important thing, don't rely on these events onLowMemory, onTrimMemory. Because they're invoked only when the entire system runs on low memory, your app can run out of memory before that. You have to track memory usage of your process and take appropriate action if it ate too much memory:

    val maxMemory = Runtime.getRuntime().maxMemory()
    val freeMemory = Runtime.getRuntime().freeMemory()
    val totalMemory = Runtime.getRuntime().totalMemory()
    val remainMemoryPercent = (freeMemory + maxMemory - totalMemory) * 100f / maxMemory
    
    // check remainMemoryPercent and take action
    
    0 讨论(0)
  • 2021-01-02 10:28

    Use the Intent Flag FLAG_ACTIVITY_REORDER_TO_FRONT

     Intent i = new Intent(ActivityD.this, ActivityA.class);
      i.setFlags(FLAG_ACTIVITY_REORDER_TO_FRONT);
     startActivity(i);
    

    This will simply bring ActivityA to the front of the stack and leave B and C where they are which I believe is what you want. Then you can obviously call finish() on D if you want to remove it from the stack.

    0 讨论(0)
  • 2021-01-02 10:34

    I was also under the impression that the system will kill old activities to free memory, according to android developer guide:

    "When the system stops one of your activities (such as when a new activity starts or the task moves to the background), the system might destroy that activity completely if it needs to recover system memory. When this happens, information about the activity state is lost. If this happens, the system still knows that the activity has a place in the back stack, but when the activity is brought to the top of the stack the system must recreate it (rather than resume it). In order to avoid losing the user's work, you should proactively retain it by implementing the onSaveInstanceState() callback methods in your activity."

    see link: android activities

    0 讨论(0)
提交回复
热议问题