问题
I am debugging an android app (which was unfortunately written by someone else). The app has a splash activity which lasts for 1 second and then the transitions to a landing page activity using an intent. The app was running fine until I noticed that the targetSDKVersion was not set in the manifest file. I set it to 18. And then when I run the app in the emulator, the app crashes and I see the following error in logcat:
10-24 06:14:26.840: E/AndroidRuntime(2457): FATAL EXCEPTION: main
10-24 06:14:26.840: E/AndroidRuntime(2457): java.lang.IllegalArgumentException: Window type can not be changed after the window is added.
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.os.Parcel.readException(Parcel.java:1435)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.os.Parcel.readException(Parcel.java:1385)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.IWindowSession$Stub$Proxy.relayout(IWindowSession.java:835)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.ViewRootImpl.relayoutWindow(ViewRootImpl.java:5034)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1399)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.Choreographer.doCallbacks(Choreographer.java:562)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.Choreographer.doFrame(Choreographer.java:532)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.os.Handler.handleCallback(Handler.java:730)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.os.Handler.dispatchMessage(Handler.java:92)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.os.Looper.loop(Looper.java:137)
10-24 06:14:26.840: E/AndroidRuntime(2457): at android.app.ActivityThread.main(ActivityThread.java:5103)
10-24 06:14:26.840: E/AndroidRuntime(2457): at java.lang.reflect.Method.invokeNative(Native Method)
10-24 06:14:26.840: E/AndroidRuntime(2457): at java.lang.reflect.Method.invoke(Method.java:525)
10-24 06:14:26.840: E/AndroidRuntime(2457): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-24 06:14:26.840: E/AndroidRuntime(2457): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-24 06:14:26.840: E/AndroidRuntime(2457): at dalvik.system.NativeStart.main(Native Method)
The app crashes immediately after showing the splash screen and before the landing page activity is loaded. The following blocks show relevant code blocks from the splash activity.
Splash Activity
private Thread mSplashThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
final SplashScreenActivity sPlashScreen = this;
mSplashThread = new Thread(){
@Override
public void run(){
try {
synchronized(this){
// Wait given period of time or exit on touch
wait(1000);
}
}
catch(InterruptedException ex){
}
finish();
// Run next activity
Intent intent = new Intent();
intent.setClass(sPlashScreen, LandingPageActivity.class);
startActivity(intent);
}
};
mSplashThread.start();
}
@Override
public boolean onTouchEvent(MotionEvent evt)
{
if(evt.getAction() == MotionEvent.ACTION_DOWN)
{
try{
synchronized(mSplashThread){
mSplashThread.notifyAll();
}
}
catch (IllegalArgumentException e){
Log.v("This is it", e.getCause().getMessage());
}
}
return true;
}
Now in all my research to debug this issue I found suggestions to check for following code piece but I don't have anything like this in my app:
@Override
public void onAttachedToWindow()
{
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
回答1:
The issue is resolved. There was indeed an occurrence of "onAttachedToWindow" in one of the empty base classes. It worked after removing that override. As I mentioned in my original post, I had come across this solution in another post. Here is a reference to that post.
In my case however this code wasn't in any of the user-facing activities. It was in a blank parent activity which my landing page was inheriting. Hope someone saves a few hours after this post.
回答2:
I have an solution for you. It is not really useful but can resolve your problem. You should change your minsdk version to 8.
<uses-sdk android:minSdkVersion="8" />
Let try it and tell me the result ;)
回答3:
If you only use delay try this;
public class MainActivity extends Activity implements OnClickListener{
private Thread mSplashThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
View root = getWindow().getDecorView().findViewById(android.R.id.content);
root.setOnClickListener(this);
final SplashScreenActivity sPlashScreen = this;
mSplashThread = new Thread(){
@Override
public void run(){
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finish();
// Run next activity
Intent intent = new Intent();
intent.setClass(sPlashScreen, LandingPageActivity.class);
startActivity(intent);
}
};
}
@Override
public void onClick(View v) {
mSplashThread.start();
}
}
来源:https://stackoverflow.com/questions/19568078/android-error-illegalargumentexception-window-type-can-not-be-changed-after