2012-06-09 36 views
1

我正在開發一款android遊戲,並且剛剛添加了一個主菜單。這是一項單獨的活動 - 所以當有人點擊菜單上的「新遊戲」按鈕時,它會打開遊戲活動的新目標。持有創建活動的引用?

我的問題是,如果用戶點擊「返回」,它會關閉遊戲並返回主菜單。當我再次擊中「新遊戲」時,它會崩潰。

我認爲它試圖製作第二個版本的遊戲,並且內存不足。我是否應該在菜單中保留一份遊戲活動的副本,然後如果他們再次點擊「新遊戲」,請重新打開它?還是有更簡單的方法來做到這一點?

我的「新遊戲」按鈕監聽器執行以下操作:(IslandGame是我的主要遊戲類 - 捆綁只是爲了告訴它是否開始新遊戲或加載以前的遊戲,以及啓動的級別)

ButtonNewGame.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) {     
      Bundle bundle = new Bundle(); 
      bundle.putString("RESTORE", "NEW"); //in the restore key, say we want a new game 
      bundle.putInt("CAMPAIGN", 1); //start in campaign #1 

      Intent intent = new Intent(Intent.ACTION_RUN); 
      intent.putExtras(bundle); 
      intent.setClassName(thisActivity, IslandGame.class.getName()); 
      startActivity(intent); 
     }   
    }); 

的logcat的是:

06-09 17:42:34.199: E/dalvikvm-heap(239): 147456-byte external allocation too large for this process. 
06-09 17:42:34.199: E/(239): VM won't let us allocate 147456 bytes 
06-09 17:42:34.209: D/AndroidRuntime(239): Shutting down VM 
06-09 17:42:34.209: W/dalvikvm(239): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 
06-09 17:42:34.219: E/AndroidRuntime(239): Uncaught handler: thread main exiting due to uncaught exception 
06-09 17:42:34.249: E/AndroidRuntime(239): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dylan.island/com.dylan.island.IslandGame}: android.view.InflateException: Binary XML file line #37: Error inflating class <unknown> 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.os.Handler.dispatchMessage(Handler.java:99) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.os.Looper.loop(Looper.java:123) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.ActivityThread.main(ActivityThread.java:4363) 
06-09 17:42:34.249: E/AndroidRuntime(239): at java.lang.reflect.Method.invokeNative(Native Method) 
06-09 17:42:34.249: E/AndroidRuntime(239): at java.lang.reflect.Method.invoke(Method.java:521) 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
06-09 17:42:34.249: E/AndroidRuntime(239): at dalvik.system.NativeStart.main(Native Method) 
06-09 17:42:34.249: E/AndroidRuntime(239): Caused by: android.view.InflateException: Binary XML file line #37: Error inflating class <unknown> 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.createView(LayoutInflater.java:513) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:565) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.rInflate(LayoutInflater.java:621) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.rInflate(LayoutInflater.java:621) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.inflate(LayoutInflater.java:407) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.Activity.setContentView(Activity.java:1622) 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.dylan.island.IslandGame.onCreate(IslandGame.java:76) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459) 
06-09 17:42:34.249: E/AndroidRuntime(239): ... 11 more 
06-09 17:42:34.249: E/AndroidRuntime(239): Caused by: java.lang.reflect.InvocationTargetException 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.dylan.island.IslandView.<init>(IslandView.java:1983) 
06-09 17:42:34.249: E/AndroidRuntime(239): at java.lang.reflect.Constructor.constructNative(Native Method) 
06-09 17:42:34.249: E/AndroidRuntime(239): at java.lang.reflect.Constructor.newInstance(Constructor.java:446) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.view.LayoutInflater.createView(LayoutInflater.java:500) 
06-09 17:42:34.249: E/AndroidRuntime(239): ... 23 more 
06-09 17:42:34.249: E/AndroidRuntime(239): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.Bitmap.nativeCreate(Native Method) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.Bitmap.createBitmap(Bitmap.java:468) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.Bitmap.createBitmap(Bitmap.java:435) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:488) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:462) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:346) 
06-09 17:42:34.249: E/AndroidRuntime(239): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:372) 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.dylan.island.IslandView$IslandThread.initimages(IslandView.java:435) 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.dylan.island.IslandView$IslandThread.beginLevel(IslandView.java:220) 
06-09 17:42:34.249: E/AndroidRuntime(239): at com.dylan.island.IslandView$IslandThread.<init>(IslandView.java:215) 
06-09 17:42:34.249: E/AndroidRuntime(239): ... 27 more 

回答

0

我認爲這是企圖讓遊戲的第二個版本,並且運行內存。

你是絕對正確的。如果你正確地完成了遊戲活動,那麼它應該試圖創建第二個版本,因爲第一個版本應該沒有了。

我應該試着在菜單中保留一份遊戲活動的副本,然後在他們再次點擊「新遊戲」時重新打開它?

一般來說,由於多種原因,這被認爲是非常糟糕的做法。其中最重要的是由於上下文而導致的內存泄漏。

還是有更簡單的方法來做到這一點?

您可以將遊戲活動定義爲singleTask或singleInstance。與此(目前)的問題是,它不是解決內存錯誤的解決方案。 SingleTasks編程方式與多實例應用程序不同,還有其他注意事項。由於您的問題在於,你已經在第一時間被使用的內存其實在這之前走這條路,我肯定會查看以下內容:

  1. 確保所有資源被釋放。這裏特別關注的是對View的靜態引用。如果你有他們,清理它們。

  2. 確保回收所有位圖。有時在調整位圖大小時,原始位置會被留下。通常是一個愚蠢的疏忽。看一看。 :)

  3. 如果您正在訪問文件,請確保它們已關閉。幾乎從來沒有問題,但總是值得一試。

  4. 遊戲活動結束後,添加System.gc()調用。這確實可以在重要資源釋放後提供幫助。不幸的是,它不能保證。在你的情況下,它可能是在主菜單的onResume()中最好的。

一旦你已用盡所有這些,那麼singleTask路線僅僅是實現的選擇。

希望這有助於

FuzzicalLogic

+0

謝謝 - 我肯定可以做清理一些內存 - 連自己是相當臃腫的圖像,我可以減少它們的大小。但是,我不希望我的「遊戲」活動完成 - 我可以從菜單中返回它嗎?例如:如果有人按下返回菜單,然後改變了一些設置,然後返回到他們正在玩的遊戲中間? – gedditoffme

+0

明白了 - 最後添加了一個確認窗口來解決任何意外的「後退」。玩了一段時間試圖釋放資源後,添加了一個循環來回收destroy()方法中的所有位圖對象。這似乎終於完成了錯誤。謝謝你的幫助。 – gedditoffme

+0

你絕對受歡迎。很高興你解決了。位圖密集型應用程序通常首次遇到這些類型的錯誤。 –

0

嘗試

Intent intent = new Intent(YourCurrentActivity.this, IslandGame.class); 
intent.putExtra("Restore", "NEW"); 
intent.putExtra("CAMPAIGN", 1); 
startActivity(intent); 

不喜歡包子易於操作。

編輯: 那麼其他活動的onCreate內:

Bundle extras = getIntent().getExtras(); 
    if(extras !=null && extras.getInt("CAMPAIGN") == 1){ 
     newGame(); 
    } 
    else{ 
     loadGame(extras.getInt("gameId")); 
     //or whatever 
    } 
0

您可以覆蓋後退按鈕的功能重新午餐:

用大量的圖片時,請參考以下鏈接獲取良好實踐主要活動並將其設置在遊戲活動之上,並在返回遊戲時執行相同操作。但由於您不確定用戶是否會再次點擊開始遊戲按鈕,這顯然是一種糟糕的做法。 而是嘗試釋放其onDestroy方法中的活動中的所有已用資源,並在用戶返回時嘗試新的實例。 也嘗試儘量減少您使用的位圖大小。例如嘗試9個小節。

0

您必須在您的Android Manifest文件中定義活動,以便只創建一個實例。

<activity 
    android:launchMode="singleTask">