0


我使用的是每個選項卡都是視圖的TabActivity。 我想在更改選項卡時創建滑動動畫。 動畫啓動logcat的每次給出了一個GC項:動畫導致垃圾回收器創建日誌條目

08-17 16:37:00.840: D/dalvikvm(2767): GC_CONCURRENT freed 1920K, 43% free 6852K/11975K, paused 12ms+14ms, total 72ms 
08-17 16:37:01.235: D/dalvikvm(2767): GC_CONCURRENT freed 1480K, 40% free 7215K/11975K, paused 2ms+3ms, total 46ms 
08-17 16:37:01.235: D/dalvikvm(2767): WAIT_FOR_CONCURRENT_GC blocked 18ms 
08-17 16:37:05.715: D/dalvikvm(2767): GC_CONCURRENT freed 2092K, 43% free 6882K/11975K, paused 12ms+28ms, total 104ms 
08-17 16:37:06.370: D/dalvikvm(2767): GC_CONCURRENT freed 779K, 34% free 7912K/11975K, paused 14ms+6ms, total 65ms 
08-17 16:37:09.825: D/dalvikvm(2767): GC_FOR_ALLOC freed 1464K, 47% free 6455K/11975K, paused 19ms, total 19ms 
08-17 16:37:09.865: D/dalvikvm(2767): GC_FOR_ALLOC freed 1K, 34% free 7988K/11975K, paused 19ms, total 19ms 
08-17 16:37:09.865: I/dalvikvm-heap(2767): Grow heap (frag case) to 16.811MB for 944656-byte allocation 
08-17 16:37:10.370: D/dalvikvm(2767): GC_CONCURRENT freed 1427K, 38% free 8706K/13959K, paused 2ms+5ms, total 41ms 

每當你點擊一個選項卡上,有兩個動畫:一個是當前標籤滑出,一個新選項卡上滑動

這些是Animation定義:

public Animation inFromRightAnimation() { 
    Animation inFromRight = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT, +1.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f); 
    inFromRight.setDuration(500); 
    return inFromRight; 
} 

public Animation outToLeftAnimation() { 
    Animation outtoLeft = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, -1.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f); 
    outtoLeft.setDuration(500); 
    return outtoLeft; 
} 

編輯:這是在標籤的改變的代碼:(currentTab是私人int類部件)

public void onTabChanged(String tabId) { 
    if (!initializatorFinished) { 
     getTabHost().setCurrentTab(currentTab); 
     return; 
    } 
    tab1 = (LinearLayout) findViewById(R.id.tabHome); 
    tab2 = (LinearLayout) findViewById(R.id.tabChanges); 
    tab3 = (LinearLayout) findViewById(R.id.tabTests); 
    tab4 = (ScrollView) findViewById(R.id.tabSettings); 
    tab5 = (LinearLayout) findViewById(R.id.tabInfo); 
    int currentTab = GetCurrentTab(); 
    int newTab = Integer.parseInt(tabId); 
     if (currentTab == 1 || currentTab == 0) { 
      if (newTab == 2) { 
       tab1.setAnimation(outToLeftAnimation()); 
       tab2.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 4) { 
       tab1.setAnimation(outToLeftAnimation()); 
       tab4.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 5) { 
       tab1.setAnimation(outToLeftAnimation()); 
       tab5.setAnimation(inFromRightAnimation()); 
      } 
     } 
     else if (currentTab == 2) { 
      if (newTab == 1) { 
       tab2.setAnimation(outToLeftAnimation()); 
       tab1.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 4) { 
       tab2.setAnimation(outToLeftAnimation()); 
       tab4.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 5) { 
       tab2.setAnimation(outToLeftAnimation()); 
       tab5.setAnimation(inFromRightAnimation()); 
      } 
     } 
     else if (currentTab == 4) { 
      if (newTab == 1) { 
       tab4.setAnimation(outToLeftAnimation()); 
       tab1.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 2) { 
       tab4.setAnimation(outToLeftAnimation()); 
       tab2.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 5) { 
       tab4.setAnimation(outToLeftAnimation()); 
       tab5.setAnimation(inFromRightAnimation()); 
      } 
     } 
     else if (currentTab == 5) { 
      if (newTab == 1) { 
       tab5.setAnimation(outToLeftAnimation()); 
       tab1.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 2) { 
       tab5.setAnimation(outToLeftAnimation()); 
       tab2.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 4) { 
       tab5.setAnimation(outToLeftAnimation()); 
       tab4.setAnimation(inFromRightAnimation()); 
      } 
     } 
     else if (currentTab == 3) { 
      if (newTab == 1) { 
       tab3.setAnimation(outToLeftAnimation()); 
       tab1.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 2) { 
       tab3.setAnimation(outToLeftAnimation()); 
       tab2.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 4) { 
       tab3.setAnimation(outToLeftAnimation()); 
       tab4.setAnimation(inFromRightAnimation()); 
      } 
      else if (newTab == 5) { 
       tab3.setAnimation(outToLeftAnimation()); 
       tab5.setAnimation(inFromRightAnimation()); 
      } 
     }   
     SetCurrentTab(Integer.parseInt(tabId)); 
    } 
private void SetCurrentTab(int tab) { 
    this.currentTab = tab; 
} 

private int GetCurrentTab() { 
    return this.currentTab; 
} 

回答

2

如果您試圖避免多餘的分配,您可以在onCreate中創建一次這些動畫,然後再簡單地引用它們,而不是每次都創建一個新的動畫。

事情是這樣的:

private Animation mInFromRight; 
private Animation mInFromLeft; 

public Animation inFromRightAnimation() { 
    return mInFromRight; 
} 

public Animation outToLeftAnimation() { 
    return mInFromLeft; 
} 

@Override 
protected void onCreate (Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    mInFromRight = new TranslateAnimation(
     Animation.RELATIVE_TO_PARENT, +1.0f, 
     Animation.RELATIVE_TO_PARENT, 0.0f, 
     Animation.RELATIVE_TO_PARENT, 0.0f, 
     Animation.RELATIVE_TO_PARENT, 0.0f); 
    mInFromRight.setDuration(500); 

    mInFromLeft = new TranslateAnimation(
     Animation.RELATIVE_TO_PARENT, 0.0f, 
     Animation.RELATIVE_TO_PARENT, -1.0f, 
     Animation.RELATIVE_TO_PARENT, 0.0f, 
     Animation.RELATIVE_TO_PARENT, 0.0f); 
    mInFromLeft.setDuration(500); 

    //...other oncreate code 
} 

除此之外,如果你仍然得到GC當你調用動畫這是你無法控制的。某處android框架正在分配作爲動畫過程一部分被破壞的對象。

GC是正常的,必要的和預計會發生的,但是你最好留意事情。大多數情況下,過度的GC是由於在框架之外發生了一些愚蠢的事情,例如不必要地在循環中分配新對象。但是框架也需要GC,在這種情況下,似乎是發生了什麼事情。

+0

我試過了,仍然沒有改變... – 2012-08-17 15:06:02

+0

然後你的動畫不會引起GC。當您的標籤變得可見時,一定是您正在做的事情。 – 2012-08-17 15:09:35

+0

不可以。當我註釋掉所有的動畫代碼時,沒有GC日誌條目。 – 2012-08-17 15:17:04

0

您在logcat中看到的條目告訴JVM執行了GC。如果啓用了GC verbose,將會打印此信息。這些是詳細的消息,在Java中,您可以通過刪除詳細信息(不確定關於android)來禁用它們。

原因可能是您的動畫吃掉了更多的內存,這迫使達爾維克執行GC。

+0

這意味着什麼?我該如何解決這個問題? – 2012-08-17 15:00:19