尝试在空对象引用上调用虚拟方法 'android.view.Window$Callback android.view.Window.getCallback()'
Posted
技术标签:
【中文标题】尝试在空对象引用上调用虚拟方法 \'android.view.Window$Callback android.view.Window.getCallback()\'【英文标题】:Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference尝试在空对象引用上调用虚拟方法 'android.view.Window$Callback android.view.Window.getCallback()' 【发布时间】:2016-08-08 13:04:32 【问题描述】:当我的SplashActivity
打开LoginActivity
时,我的应用程序崩溃了。
以下是我的SplashActivity.java
:
package com.example.android.appName;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import java.util.Timer;
import java.util.TimerTask;
public class SplashActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Timer timer = new Timer();
timer.schedule(new TimerTask()
public void run()
Intent intent = new Intent(SplashActivity.this, LoginActivity.class);
startActivity(intent);
finish();
, 1500);
还有我的LoginActivity.java
:
package com.example.android.appName;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
public class LoginActivity extends AppCompatActivity
private EditText usernameField = (EditText)findViewById(R.id.username),
passwordField = (EditText)findViewById(R.id.password);
private TextView error = (TextView)findViewById(R.id.error);
private ProgressBar progress = (ProgressBar)findViewById(R.id.progress);
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.login_menu, menu);
return true;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
if (android.os.Build.VERSION.SDK_INT > 5
&& keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0)
onBackPressed();
return true;
return super.onKeyDown(keyCode, event);
public void exit(MenuItem item)
finish();
public void signIn(View view)
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
AndroidManifest.xml
的一部分:
<activity android:name=".SplashActivity"
android:theme="@style/NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".LoginActivity"
android:label="@string/title_activity_login" />
logcat 中的错误:
04-16 23:24:16.124 4015-4015/com.example.android.appName E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.appName, PID: 4015
java.lang.RuntimeException: Unable to instantiate activity ComponentInfocom.example.android.appName/com.example.android.appName.LoginActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2993)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3248)
at android.app.ActivityThread.access$1000(ActivityThread.java:197)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1681)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6872)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:68)
at android.support.v7.app.AppCompatDelegateImplV7.<init>(AppCompatDelegateImplV7.java:145)
at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:28)
at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:42)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:186)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:168)
at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:508)
at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:180)
at com.example.android.appName.LoginActivity.<init>(LoginActivity.java:20)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1690)
at android.app.Instrumentation.newActivity(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2983)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3248)
at android.app.ActivityThread.access$1000(ActivityThread.java:197)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1681)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6872)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
【问题讨论】:
您是否在清单中声明了您的 LoginActivity? @NicolasSimon 是的,我做到了TimerTask.run()
不在 UI 线程上执行。如果你从 UI 线程开始你的活动,它会起作用吗?
@GeorgeMulligan 抱歉,我不太清楚您所说的“在 UI 线程上执行”是什么意思 :(
你能显示LoginActivity
的完整代码吗?或者至少类上所有声明的字段和完整的onCreate()
开始。
【参考方案1】:
在onCreate()
中调用setContentView(...)
之前,Activity
尚未完全初始化并准备好查找视图。
只声明如下字段:
private EditText usernameField, passwordField;
private TextView error;
private ProgressBar progress;
然后在onCreate
中赋值:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
usernameField = (EditText)findViewById(R.id.username);
passwordField = (EditText)findViewById(R.id.password);
error = (TextView)findViewById(R.id.error);
progress = (ProgressBar)findViewById(R.id.progress);
可能不是问题的一部分,但作为一个额外的建议,Timer
在后台线程上运行TimerTask
,在这种情况下应该避免这种情况。将 Timer
替换为 Handler
以在 UI 线程上运行它。
new Handler().postDelayed(new Runnable()
@Override
public void run()
Intent intent = new Intent(SplashActivity.this, LoginActivity.class);
startActivity(intent);
finish();
, 1500);
【讨论】:
这并没有解决问题,但是感谢Handler
:)
确实如此!非常感谢 :P 顺便说一句,我真的希望 Android Studio 有朝一日能提供比这更有用和更清晰的错误消息...
我同意特定的堆栈跟踪对于确定如何解决问题不是很有帮助。生命周期回调和项目配置之外的大多数其他错误消息更容易理解。
"在 onCreate() 中调用 setContentView(...) 之前,Activity 尚未完全初始化并准备好查找视图。"发现 。谢谢
即使在 onCreate()
中将值分配给我的按钮 id 后,我仍然收到相同的错误 @GeorgeMulligan【参考方案2】:
在将ContentView
设置为所需的xml文件后,xml文件中定义的视图只能在java代码中访问:
setContentView(R.layout.xml_file_name);
因此,第一次在 onCreate
方法内调用上述方法,然后在 onCreate
或将使用该实例的方法内初始化 View
实例。
【讨论】:
以上是关于尝试在空对象引用上调用虚拟方法 'android.view.Window$Callback android.view.Window.getCallback()'的主要内容,如果未能解决你的问题,请参考以下文章
尝试在空对象引用上调用虚拟方法 'android.graphics.Rect android.graphics.drawable.Drawable.getBounds()'
尝试在空对象引用上调用虚拟方法 'android.view.Window$Callback android.view.Window.getCallback()'
尝试在空对象引用上调用虚拟方法 'android.os.Handler android.support.v4.app.FragmentHostCallback.getHandler()'
尝试在空对象引用上调用虚拟方法 'void android.view.View.measure(int, int)'