我有一个带有按钮“新游戏”的MenuActivity按下这个,MenuActivity应该完全清理,这样你就无法返回它并开始新的活动。因此,目标是完全清空MenuActivity所持有的内存。但我可以从eclipse中的DDMS看到,在调用unbindDrawables()和finish()之后仍然没有释放12621MB内存,你可以从屏幕截图中看到,但我需要它为0 MB
activity_menu.xml:
<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"
tools:context=".MenuActivity"
android:background="@drawable/menu_background"
android:id = "@+id/menu_layout" >
<RelativeLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="47dp"
android:layout_marginTop="148dp"
android:id="@+id/board_layout"
android:visibility="gone">
<ImageButton
android:id="@+id/sound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="110dp"
android:background="@drawable/on"
android:onClick="change"
android:tag="on"
android:visibility="gone"/>
<ImageButton
android:id="@+id/ad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@+id/sound"
android:background="@drawable/on"
android:onClick="change"
android:tag="on"
android:visibility="gone"/>
<TextView
android:id="@+id/credits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="125dp"
android:layout_marginLeft="120dp"
android:text="@string/credits"
android:clickable="true"
android:onClick="playCredits"
android:textSize="25sp"
android:textColor="#FFFFF0"
android:visibility="gone"
>
</TextView>
<TextView
android:id="@+id/delimiter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/credits"
android:layout_toRightOf="@+id/credits"
android:text=" | "
android:textSize="25sp"
android:textColor="#FFFFF0"
android:visibility="gone"
>
</TextView>
<TextView
android:id="@+id/subscribe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/credits"
android:layout_toRightOf="@+id/delimiter"
android:text="@string/subscribe"
android:clickable="true"
android:onClick="subscribe"
android:textSize="25sp"
android:textColor="#FFFFF0"
android:visibility="gone">
</TextView>
<Button
android:id="@+id/fire"
android:layout_width="70dp"
android:layout_height="65dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="65dp"
android:onClick="previewFireRoom"
android:visibility = "gone"/>
<Button
android:id="@+id/water"
android:layout_width="70dp"
android:layout_height="65dp"
android:layout_centerVertical="true"
android:layout_alignTop="@id/fire"
android:layout_toRightOf="@id/fire"
android:layout_marginLeft="25dp"
android:onClick="previewWaterRoom"
android:visibility = "gone"/>
<Button
android:id="@+id/earth"
android:layout_width="70dp"
android:layout_height="65dp"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/water"
android:layout_marginLeft="25dp"
android:onClick="previewEarthRoom"
android:visibility = "gone"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/left_menu"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="40dp"
android:layout_alignParentRight="true"
android:layout_marginRight="30dp"
>
<TextView
android:id="@+id/new_game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="new game"
android:textSize="25sp"
android:textColor="#FFFFF0"
android:onClick="newGame"
android:clickable="true"
/>
<TextView
android:id="@+id/resume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:text="resume"
android:textSize="25sp"
android:textColor="#FFFFF0"
android:onClick="resume"
android:clickable="true"
/>
<TextView
android:id="@+id/settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="125dp"
android:text="settings"
android:textSize="25sp"
android:textColor="#FFFFF0"
android:onClick="settings"
android:clickable="true"
/>
<TextView
android:id="@+id/walkthroughs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:text="walkthrou"
android:textSize="25sp"
android:textColor="#FFFFF0"
android:onClick="walkthrough"
android:clickable="true"
/>
<TextView
android:id="@+id/about"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="255dp"
android:text="about"
android:textSize="25sp"
android:textColor="#FFFFF0"
android:onClick="about"
android:clickable="true"
/>
</RelativeLayout>
</RelativeLayout>
MenuActivity:
public class MenuActivity extends Activity {
Intent intent;
Typeface tf;
TextView newgame,resume,settings,walkthroughs,about;
int walkthrough_board = R.drawable.walkthrough;
int settings_board = R.drawable.settings;
int about_board = R.drawable.about;
RelativeLayout boardLayout;
int on = R.drawable.on;
int off = R.drawable.off;
int walkthrough_clicked, about_clicked, settings_clicked = 0;
private final String TAG = "Lifecycle ";
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
newgame = (TextView)((RelativeLayout)this.findViewById(R.id.left_menu)).findViewById(R.id.new_game);
resume = (TextView)this.findViewById(R.id.resume);
settings = (TextView)this.findViewById(R.id.settings);
walkthroughs = (TextView)this.findViewById(R.id.walkthroughs);
about = (TextView)this.findViewById(R.id.about);
tf = Typeface.createFromAsset(getAssets(),"fonts/Livingst.ttf");
newgame.setTypeface(tf);
resume.setTypeface(tf);
settings.setTypeface(tf);
walkthroughs.setTypeface(tf);
about.setTypeface(tf);
about.setTypeface(tf);
boardLayout = (RelativeLayout)this.findViewById(R.id.board_layout);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_menu, menu);
return true;
}
public void start(View v)
{
intent = new Intent(this, FireRoomActivity.class);
startActivity(intent);
}
public void newGame(View view){
Intent intent = new Intent(this, FireRoomActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
unbindDrawables(findViewById(R.id.menu_layout));
this.finish();
startActivity(intent);
}
static void unbindDrawables(View view) {
try{
Log.d("unbinding", view.toString());
if (view.getBackground() != null) {
((BitmapDrawable)view.getBackground()).getBitmap().recycle();
view.getBackground().setCallback(null);
view=null;
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
protected void onPause() {
Log.d(TAG, "onPause");
super.onPause();
}
@Override
protected void onRestart() {
Log.d(TAG, "onRestart");
super.onRestart();
}
@Override
protected void onStart() {
Log.d(TAG, "onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.d(TAG, "onStop");
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
public void resume(View view){
changeColor(view);
}
public void settings(View view){
if(settings_clicked == 0){
settings_clicked++;
if(walkthrough_clicked == 1){
changeColorBack(findViewById(R.id.walkthroughs));
closeWalkthroughBoard();
walkthrough_clicked = 0;
}
if(about_clicked == 1){
changeColorBack(findViewById(R.id.about));
closeAboutBoard();
about_clicked = 0;
}
changeColor(view);
boardLayout.setBackgroundResource(settings_board);
boardLayout.setVisibility(View.VISIBLE);
boardLayout.findViewById(R.id.sound).setVisibility(View.VISIBLE);
boardLayout.findViewById(R.id.ad).setVisibility(View.VISIBLE);
}
else if(settings_clicked == 1){
changeColorBack(view);
boardLayout.setVisibility(View.INVISIBLE);
closeSettingsBoard();
settings_clicked = 0;
}
}
public void walkthrough(View view){
if(walkthrough_clicked == 0){
if(settings_clicked == 1){
closeSettingsBoard();
changeColorBack(findViewById(R.id.settings));
settings_clicked = 0;
}
if(about_clicked == 1){
closeAboutBoard();
changeColorBack(findViewById(R.id.about));
about_clicked = 0;
}
changeColor(view);
boardLayout.setBackgroundResource(walkthrough_board);
boardLayout.setVisibility(View.VISIBLE);
boardLayout.findViewById(R.id.water).setVisibility(View.VISIBLE);
boardLayout.findViewById(R.id.earth).setVisibility(View.VISIBLE);
boardLayout.findViewById(R.id.fire).setVisibility(View.VISIBLE);
walkthrough_clicked++;}
else{
changeColorBack(view);
walkthrough_clicked = 0;
boardLayout.setVisibility(View.INVISIBLE);
closeWalkthroughBoard();
}
}
public void about(View view){
if(about_clicked == 0){
if(settings_clicked == 1){
closeSettingsBoard();
changeColorBack(findViewById(R.id.settings));
settings_clicked = 0;
}
if(walkthrough_clicked == 1){
closeWalkthroughBoard();
changeColorBack(findViewById(R.id.walkthroughs));
walkthrough_clicked = 0;
}
changeColor(view);
about_clicked++;
boardLayout.setBackgroundResource(about_board);
boardLayout.setVisibility(View.VISIBLE);
boardLayout.findViewById(R.id.credits).setVisibility(View.VISIBLE);
boardLayout.findViewById(R.id.subscribe).setVisibility(View.VISIBLE);}
else if(about_clicked == 1){
changeColorBack(view);
about_clicked = 0;
boardLayout.setVisibility(View.INVISIBLE);
closeAboutBoard();
}
}
private void changeColorBack(View view) {
((TextView)view).setTextColor(Color.parseColor("#FFFFF0"));
}
private void changeColor(View view) {
((TextView)view).setTextColor(Color.parseColor("#FFDF00"));
}
public void change(View view){
String state = (String)view.getTag();
if(state.equals("on")){
view.setTag("off");
view.setBackgroundResource(off);
}
else if(state == "off"){
view.setTag("on");
view.setBackgroundResource(on);
}
}
private void closeAboutBoard(){
boardLayout.findViewById(R.id.credits).setVisibility(View.INVISIBLE);
boardLayout.findViewById(R.id.subscribe).setVisibility(View.INVISIBLE);
}
private void closeSettingsBoard(){
boardLayout.findViewById(R.id.sound).setVisibility(View.INVISIBLE);
boardLayout.findViewById(R.id.ad).setVisibility(View.INVISIBLE);
}
private void closeWalkthroughBoard(){
boardLayout.findViewById(R.id.water).setVisibility(View.INVISIBLE);
boardLayout.findViewById(R.id.earth).setVisibility(View.INVISIBLE);
boardLayout.findViewById(R.id.fire).setVisibility(View.INVISIBLE);
}
}
unbindDrawableMethod()或某种内存泄漏中是否有任何遗漏?
答案 0 :(得分:0)
执行堆转储(在从DDMS手动调用GC之后)并使用内存分析工具查看正在保留的对象。您可以看到内存泄漏的位置。见http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html
答案 1 :(得分:0)
你不可挽回的人是我见过的最具攻击性的,而且我不是百分之百,因为你打电话给finish()
这是值得的,所以让我们来看看。
public void newGame(View view){
Intent intent = new Intent(this, FireRoomActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
unbindDrawables(findViewById(R.id.menu_layout));
this.finish();
startActivity(intent);
System.gc(); // call garbage collector
}
现在您应该在DDMS / monitor中看到堆大小更改。