2012-05-04 2 views
1

Мое приложение отлично работает при первом запуске. Затем, когда я завершаю его и запускаю снова, он просто вызывает окно закрытия силы. После того, как я закрою приложение, он снова работает отлично. Приложение чередует силу близко и работает нормально.android app force close on second run

Я пропустил некоторую очистку до того, как приложение завершится?

Ниже некоторые из моего кода (содержит три класса, Foobar, ActionView & actionthread:

foobar.java:

public class foobar extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(new ActionView(this)); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
    } 
} 

public class ActionView extends SurfaceView implements SurfaceHolder.Callback { 

    private ActionThread actionThread; 

    public ActionView(Context context) 
    { 
     super(context); 
     getHolder().addCallback(this); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) 
    { 
     actionThread = new ActionThread(holder,this); 
     actionThread.setRunning(true); 
     actionThread.start(); 
     } 


    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) 
    { 
     boolean retry = true; 
     while(retry) 
     { 
      try 
      { 
       actionThread.join(); 
       retry=false; 
      } 
      catch(InterruptedException e) 
      { 
      } 
     } 
    } 

    protected void displayGameState(Canvas canvas) 
    { 
     //code... 
     } 

     public void updateGameState() 
    { 
     //code.. 
     if something happens then 
    actionThread.setRunning(false); 
    ((Activity)getContext()).finish(); 

     } 
} 

ActionThread.java:

public class ActionThread extends Thread { 

    private boolean threadIsRunning; 
    private SurfaceHolder surfaceHolder; 
    private ActionView actionView; 
    private final static int MAX_FPS = 50; 
    private final static int MAX_FRAME_SKIPS = 5; 
    private final static int FRAME_PERIOD = 1000/MAX_FPS; 
    private static final String TAG = ActionThread.class.getSimpleName(); 

    public ActionThread(SurfaceHolder holder, ActionView actionView) { 
     this.actionView= actionView; 
     surfaceHolder = holder; 
    } 

    public void setRunning(boolean running) 
    { 
     threadIsRunning = running; 
    } 

    @Override 
    public void run() 
    { 
     long tickCount = 0L; 
     long totalFramesSkipped = 0L; 
     Canvas canvas = null; 
     long beginTime; //time the cycle began 
     long timeDiff; //time it took for cycle to execute 
     int sleepTime; //milliseconds to sleep (< 0 if time it took to complete cycle is longer than FRAME_PERIOD 
     int framesSkipped; //# of frames being skipped 

     while(threadIsRunning) 
     { 
      tickCount++; 
      try 
      { 
       canvas = surfaceHolder.lockCanvas(); 
       synchronized(surfaceHolder) 
       { 
        beginTime = System.currentTimeMillis(); 
        framesSkipped = 0; 

        actionView.updateGameState(); 
        actionView.displayGameState(canvas); 

        //calc how long the cycle took 
        timeDiff = System.currentTimeMillis() - beginTime; 
        //calc sleep time 
        sleepTime = (int)(FRAME_PERIOD - timeDiff); 

        if(sleepTime > 0) 
        { 
         //if sleepTime > 0 , didn't fall behind. Try to sleep 
         try 
         { 
          Thread.sleep(sleepTime); 
         } 
         catch(InterruptedException e){} 
        } 
        while(sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) 
        { //fell behind and need to catch up (update without displaying) 
         actionView.updateGameState(); 
         sleepTime+=FRAME_PERIOD; //add frame period to check if in next frame 
         framesSkipped++; 
         totalFramesSkipped++; 
        } 
       } 
      } 
      finally 
      { 
       if(canvas != null) 
       { 
        surfaceHolder.unlockCanvasAndPost(canvas); 
       } 
      } 
     } 
    } 

} 

Вот ошибка logcat:

05-03 22:47:45.449: D/dalvikvm(30596): GC_EXTERNAL_ALLOC freed <1K, 43% free 3126K/5447K, external 36955K/38794K, paused 32ms 
05-03 22:47:45.488: I/dalvikvm-heap(30596): Clamp target GC heap from 43.427MB to 42.000MB 
05-03 22:47:45.488: D/dalvikvm(30596): GC_FOR_MALLOC freed 0K, 43% free 3126K/5447K, external 37165K/38794K, paused 18ms 
05-03 22:47:45.535: D/dalvikvm(30596): GC_EXTERNAL_ALLOC freed <1K, 43% free 3126K/5447K, external 37165K/38794K, paused 29ms 
05-03 22:47:45.574: I/dalvikvm-heap(30596): Clamp target GC heap from 43.674MB to 42.000MB 
05-03 22:47:45.582: D/dalvikvm(30596): GC_FOR_MALLOC freed 0K, 43% free 3126K/5447K, external 37418K/38794K, paused 18ms 
05-03 22:47:45.613: D/dalvikvm(30596): GC_EXTERNAL_ALLOC freed <1K, 43% free 3126K/5447K, external 37244K/38794K, paused 30ms 
05-03 22:47:45.652: I/dalvikvm-heap(30596): Clamp target GC heap from 43.804MB to 42.000MB 
05-03 22:47:45.652: D/dalvikvm(30596): GC_FOR_MALLOC freed 0K, 43% free 3126K/5447K, external 37551K/38794K, paused 17ms 
05-03 22:47:45.684: D/dalvikvm(30596): GC_EXTERNAL_ALLOC freed <1K, 43% free 3126K/5447K, external 37551K/38794K, paused 27ms 
05-03 22:47:45.699: E/dalvikvm-heap(30596): 258908-byte external allocation too large for this process. 
05-03 22:47:45.723: I/dalvikvm-heap(30596): Clamp target GC heap from 43.804MB to 42.000MB 
05-03 22:47:45.723: D/dalvikvm(30596): GC_FOR_MALLOC freed <1K, 43% free 3126K/5447K, external 37551K/38794K, paused 17ms 
05-03 22:47:45.723: D/GraphicsJNI(30596): Waiting for heap walker to free more memory 
05-03 22:47:45.723: D/GraphicsJNI(30596): Heap walker done, retry to allocate 
05-03 22:47:45.754: D/dalvikvm(30596): GC_EXTERNAL_ALLOC freed <1K, 43% free 3126K/5447K, external 37298K/38794K, paused 27ms 
05-03 22:47:45.793: I/dalvikvm-heap(30596): Clamp target GC heap from 43.804MB to 42.000MB 
05-03 22:47:45.793: D/dalvikvm(30596): GC_FOR_MALLOC freed 0K, 43% free 3126K/5447K, external 37551K/38794K, paused 17ms 
05-03 22:47:45.832: D/dalvikvm(30596): GC_EXTERNAL_ALLOC freed <1K, 43% free 3126K/5447K, external 37551K/38794K, paused 26ms 
05-03 22:47:45.840: E/dalvikvm-heap(30596): 313968-byte external allocation too large for this process. 
05-03 22:47:45.871: I/dalvikvm-heap(30596): Clamp target GC heap from 43.804MB to 42.000MB 
05-03 22:47:45.871: D/dalvikvm(30596): GC_FOR_MALLOC freed 0K, 43% free 3126K/5447K, external 37551K/38794K, paused 17ms 
05-03 22:47:45.871: D/GraphicsJNI(30596): Waiting for heap walker to free more memory 
05-03 22:47:45.871: D/GraphicsJNI(30596): Heap walker done, retry to allocate 
05-03 22:47:45.902: D/dalvikvm(30596): GC_EXTERNAL_ALLOC freed <1K, 43% free 3126K/5447K, external 37551K/38794K, paused 30ms 
05-03 22:47:45.910: E/dalvikvm-heap(30596): 313968-byte external allocation too large for this process. 
05-03 22:47:45.941: I/dalvikvm-heap(30596): Clamp target GC heap from 43.804MB to 42.000MB 
05-03 22:47:45.941: D/dalvikvm(30596): GC_FOR_MALLOC freed 0K, 43% free 3126K/5447K, external 37551K/38794K, paused 17ms 
05-03 22:47:45.941: E/GraphicsJNI(30596): VM won't let us allocate 313968 bytes 
05-03 22:47:45.957: D/AndroidRuntime(30596): Shutting down VM 
05-03 22:47:45.957: W/dalvikvm(30596): threadid=1: thread exiting with uncaught exception (group=0x4001e560) 
05-03 22:47:45.965: E/AndroidRuntime(30596): FATAL EXCEPTION: main 
05-03 22:47:45.965: E/AndroidRuntime(30596): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.graphics.Bitmap.nativeCreate(Native Method) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.graphics.Bitmap.createBitmap(Bitmap.java:507) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.graphics.Bitmap.createBitmap(Bitmap.java:474) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:379) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at com.somecomany.foobar.Element.Element.resizeBitmap(Element.java:48) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at com.somecomany.foobar.Element.Element.<init>(Element.java:31) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at com.somecomany.foobar.Element.MobileElement.<init>(MobileElement.java:24) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at com.somecomany.foobar.ActionView.surfaceCreated(ActionView.java:156) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.SurfaceView.updateWindow(SurfaceView.java:543) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.SurfaceView.dispatchDraw(SurfaceView.java:348) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.View.draw(View.java:6883) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.View.draw(View.java:6883) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2106) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.ViewRoot.draw(ViewRoot.java:1562) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.ViewRoot.performTraversals(ViewRoot.java:1298) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.view.ViewRoot.handleMessage(ViewRoot.java:1911) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.os.Handler.dispatchMessage(Handler.java:99) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.os.Looper.loop(Looper.java:130) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at android.app.ActivityThread.main(ActivityThread.java:3821) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at java.lang.reflect.Method.invokeNative(Native Method) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at java.lang.reflect.Method.invoke(Method.java:507) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
05-03 22:47:45.965: E/AndroidRuntime(30596): at dalvik.system.NativeStart.main(Native Method) 
05-03 22:47:49.996: I/Process(30596): Sending signal. PID: 30596 SIG: 9 
+1

Показать ошибку logcat. –

+0

Мое предположение заключается в том, что он не останавливает петлю обзора поверхности и что из-за этого он не отпирает холст. убедитесь, что остановили просмотр поверхности в своем ondestroy своей активности. – L7ColWinters

+0

Нам нужен вывод logcat, чтобы определить, что не так. –

ответ

1

Из журнала, похоже, что у вас есть утечка памяти при создании растровых изображений, что происходит, когда у вас есть объекты большого размера, висящие вокруг, возможно, через статические структуры данных, когда приложение запускается во второй раз.

Другой вариант сценария - это когда вы ссылаетесь на контекст или активность в статической переменной, которая в основном предотвратила бы сбор данных из предыдущего Activity.

Это происходит, потому что, когда вы «выходите» из приложения в Android, его процесс не обязательно завершается. Таким образом, при повторном запуске ОС может пропустить некоторые трудоемкие шаги, и приложение может быть запущено быстрее. Это хорошо, когда вы сохраняете некоторые свои данные для быстрого повторного использования, и это очень плохо, когда вы непреднамеренно сохраняете некоторые из ваших (огромных) данных, а затем пытаетесь воссоздать эти данные снова, вот когда все идет бум.

+0

, как вы гарантируете уничтожение всех объектов (независимо от того, статичны они или нет)? Как-то вроде простого команда, возможно, помещена в метод onPause? Я пробовал настройку активности: launchMode to SingleTop в манифесте, как предлагает Changwei ниже, но это не имело желаемого эффекта. – newyorkgena

+0

Kai, я удалил статическое из своего приложения, таким образом сделав любые статические переменные, -static.К сожалению, он по-прежнему дает ту же ошибку. – newyorkgena

+0

activity: launchMode не имеет ничего общего с управлением памятью. Для этого вам нужно использовать профилирование памяти, чтобы проверить, где протекают утечки памяти. Проверьте это: http: //stackoverflow.com/questions/3112671/android-memory-analysing-eclipse-memory-analyzer и это: http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html – Kai

0

Попробуйте установить LaunchMode Activity на SingleTop.

И вы должны освободить ресурсы, когда будет выполняться операция onDestroy. удачи.

+0

Я добавил андроид: launchMode = "singleTop", но не повезло :(все равно дайте силу закрыть каждый второй прогон – newyorkgena