解开drawables并完成后,内存不会被清除

时间:2013-11-19 18:24:58

标签: android memory-leaks activity-finish

我有一个带有按钮“新游戏”的MenuActivity按下这个,MenuActivity应该完全清理,这样你就无法返回它并开始新的活动。因此,目标是完全清空MenuActivity所持有的内存。但我可以从eclipse中的DDMS看到,在调用unbindDrawables()和finish()之后仍然没有释放12621MB内存,你可以从屏幕截图中看到,但我需要它为0 MB DDMS screenshot

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()或某种内存泄漏中是否有任何遗漏?

2 个答案:

答案 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中看到堆大小更改。