android中堆栈内存分配,内存不足时,Android不会从堆栈中终止活动

我们一直在开发具有下拉式仪表板的应用程序,该仪表板允许用户在整个应用程序中导航。导航不是很标准,因为几乎每个活动都可以访问此菜单。

在使用菜单玩了一段时间的活动后,堆栈开始逐渐增长。

所有这些活动都包含带有多个imageview的listview,每个视图占用3mb的空间。如果用户玩够了,并在堆栈上创建了25个以上的活动,则会发生以下情况:

发生内存不足错误(堆增加,直到没有更多堆为止)。

由于出现异常,将显示一个对话框(不幸的是,%activity%已停止。)

引发内存不足错误的活动已完成。

堆栈中的所有活动均已完成,但历史记录已保留,因此可以进行备份,并且每个活动都将由OS自动重新创建。

我期望系统在抛出OutOfMemoryError之前自动杀死堆栈中最古老的活动...

为了确保操作系统不会杀死旧活动,我创建了一个测试应用程序,每次分配1mb。猜猜是什么:行为是相同的,并且抛出了outofmemerror:

问题是:如果需要,我们如何告诉Android OS允许取消分配活动及其资源,所以我们不会收到"很遗憾,您的活动已停止"。对话?

概念证明

package com.gaspar.memorytest;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class MemoryTestActivity extends Activity {

/** Called when the activity is first created. */

private byte[] mData;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main1);

((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

Intent i = new Intent(MemoryTestActivity.this, MemoryTestActivity.class);

startActivity(i);

}

});

mData = new byte[1*1024*1024];

}

}

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

Android不会这样做。 Android终止进程以释放系统内存以供其他进程使用。它不会以类似的方式参与应用程序内内存的使用。

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?

你不能

相反,您需要设计应用程序以使用较少的活动,或每个活动使用较少的资源。例如,您可以通过FLAG_ACTIVITY_REORDER_TO_FRONT"回收"现有活动实例,或者(如Tornquist先生所指出的那样),您可以自己手动finish()活动。

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

您可能应该在这些菜单项上使用FLAG_ACTIVITY_REORDER_TO_FRONT,以便将现有活动带入任务中,而不是每次都创建新活动。

谢谢!目前,我们将使用建议的标志FLAG_ACTIVITY_REORDER_TO_FRONT并实现onNewIntent回调以确保使用新的意图更新了活动。

@commonsware,该文档确实说可以从堆栈中终止特定的Activity。"暂停的活动是完全活着的(...),但是在极端内存不足的情况下,系统可以将其杀死。"和"(已停止的活动)仍然保留所有状态和成员信息,但是,用户不再可见它,因此它的窗口被隐藏了,当其他地方需要内存时,它通常会被系统杀死。" (链接developer.android.com/reference/android/app/Activity.html)。这就是"不保留活动"工具的确切工作方式...

@Alesqui:Android仅会终止整个过程。

开始新活动时调用finish()将取消分配要离开的活动。这样可以防止您使用"后退"按钮访问它,但是它会使内存减少。

谢谢,您的解决方案应该可以工作,但是它也可以从堆栈中删除被破坏的活动。病态遵循CommonsWare的建议,因为历史至少与一种活动保持在一起。

使用意图标志FLAG_ACTIVITY_REORDER_TO_FRONT

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

i.setFlags(FLAG_ACTIVITY_REORDER_TO_FRONT);

startActivity(i);

这只会将ActivityA移到堆栈的最前面,而B和C留在我想要的位置。然后,如果要将其从堆栈中删除,显然可以在D上调用finish()。

根据android开发人员指南,我还对系统会杀死旧活动以释放内存有一种印象:

"当系统停止您的一项活动时(例如新活动开始时或任务移至后台时,如果系统需要恢复系统内存,则系统可能会完全销毁该活动。发生这种情况时,有关该活动状态的信息如果发生这种情况,系统仍会知道该活动在后堆栈中具有位置,但是当将活动移到堆栈的顶部时,系统必须重新创建它(而不是继续它)。丢失用户的工作,您应该通过在活动中实现onSaveInstanceState()回调方法来主动保留它。"

见链接:

android活动

但是正如几个月前公认的答案所指出的,情况并非如此。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值