R
R
Regdan2014-05-08 21:22:25
Android
Regdan, 2014-05-08 21:22:25

Android: Activity::onCreate() crashes every 2nd run on setContentView()?

I'm learning programming for Android, and in the process of writing a test program I came across an incomprehensible problem. If you run the program from ADT, then everything works great, but if you directly click on the shortcut on the device, then every second launch will crash with an error.

Error message

05-08 19:38:28.173: E/AndroidRuntime(21382): FATAL EXCEPTION: main
05-08 19:38:28.173: E/AndroidRuntime(21382): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.inputtest/com.example.inputtest.MainActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1659)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1675)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.ActivityThread.access$1500(ActivityThread.java:121)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.os.Handler.dispatchMessage(Handler.java:99)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.os.Looper.loop(Looper.java:130)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.ActivityThread.main(ActivityThread.java:3701)
05-08 19:38:28.173: E/AndroidRuntime(21382): at java.lang.reflect.Method.invokeNative(Native Method)
05-08 19:38:28.173: E/AndroidRuntime(21382): at java.lang.reflect.Method.invoke(Method.java:507)
05-08 19:38:28.173: E/AndroidRuntime(21382): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
05-08 19:38:28.173: E/AndroidRuntime(21382): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
05-08 19:38:28.173: E/AndroidRuntime(21382): at dalvik.system.NativeStart.main(Native Method)
05-08 19:38:28.173: E/AndroidRuntime(21382): Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.view.ViewGroup.addViewInner(ViewGroup.java:2069)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.view.ViewGroup.addView(ViewGroup.java:1964)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.view.ViewGroup.addView(ViewGroup.java:1944)
05-08 19:38:28.173: E/AndroidRuntime(21382): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:246)
05-08 19:38:28.173: E/AndroidRuntime(21382): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:236)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.Activity.setContentView(Activity.java:1668)
05-08 19:38:28.173: E/AndroidRuntime(21382): at com.example.inputtest.MainActivity.onCreate(MainActivity.java:30)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-08 19:38:28.173: E/AndroidRuntime(21382): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1623)

The error says about extra View elements that need to be removed. Google finds a similar problem, but it usually occurs when re-creating View elements. I don’t have any elements, because the program has just started. Therefore, it seems that something remains from the previous launch. How is this possible and how to catch it?
Actually code:
public class MainActivity extends Activity implements SensorEventListener
{
  private static MainActivity instance;
  public  static MainActivity getInstance(){ return instance; }
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    instance = this;
    setContentView(GameMainView.getInstance());
  }
  ...
}

public class GameMainView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener
{
  private static GameMainView instance;
  public static GameMainView getInstance()
  {
    if(instance==null) instance = new GameMainView(MainActivity.getInstance());
    return instance;
  };
  private GameMainView(Context context)
  {
    super(context);
 		SHolder = getHolder();
        	SHolder.addCallback(this);
        	setOnTouchListener(this);
  }
  ...	
}

Answer the question

In order to leave comments, you need to log in

5 answer(s)
O
one pavel, 2014-05-08
@Regdan

I guess the problem is keeping the activity instance in static

D
dr_yand, 2014-05-09
@dr_yand

If you run the program from ADT, then everything works great, but if you directly click on the shortcut on the device, then every second launch will crash with an error.

How do you end the application?
Perhaps the activation is simply being minimized, but the application remains in memory.
When you run an application from the development environment, the application stops.

R
Regdan, 2014-05-09
@Regdan

Yes, onepavel is right, the problem was indeed static. For some reason, static variables are saved in memory after the application is restarted. Perhaps dr_yand You are right and I really did not take into account something when completing the application, but that's another question. Thanks for answers.

B
belozerow, 2014-05-09
@belozerow

static context is the worst of evils. A static context is not only an activity and, in fact, the context itself, but also a view and everything else that refers to the context.
android-developers.blogspot.co.il/2009/01/avoiding...

S
StanKo, 2014-05-12
@StanKo

For some reason, static variables are saved in memory after the application is restarted.

There is a reason for this and it lies in the cunning "completion" of applications in the AOS. In fact, the applications are not "killed" by the system, they are further hanging out in the RAM of the bucket, in order to "optimize" the time to restart this application. There is no visible logic here, as with the "fork and plate", and the statics therefore "survive". Your code, although unconditionally wrong due to the use of a context reference in the static field, could in principle work if exiting the application were a real exit, i.e. the application and all processes would be killed by the system, in fact there is a crutch for this, but I will not give it in order to protect it from incorrect programming.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question