我正在尝试创建一个程序,该程序接收太阳和行星的某些参数,并在扩展的SurfaceView类Surface中渲染可居住区域。我可以让它运行,只要我不尝试从主活动类访问Surface的任何成员,但Surface不会显示。当我尝试访问一个成员时,程序崩溃,我得到一个NullPointerException。
以下是HabitableActivity.java(主要活动)的相关部分:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialize variables
surface = (Surface) findViewById(R.id.surface);
A = 0.4;
liveMin = 1.0;
liveMax = 5.0;
planet = BitmapFactory
.decodeResource(getResources(), R.drawable.planet);
sun = BitmapFactory.decodeResource(getResources(), R.drawable.sun);
setContentView(R.layout.activity_habitable);
//surface.resetSurface(); // uncomment this and it crashes
}
和Surface.java:
public class Surface extends SurfaceView implements Runnable, OnTouchListener {
float x, y;
double scale;
Bitmap planet, sun;
Paint paint = new Paint();
SurfaceHolder holder;
Thread thread = null;
boolean isRunning = false;
// TODO: delete these temp vars
double liveMin = 1.0;
double liveMax = 5.0;
public Surface(Context context, AttributeSet attrs) {
super(context, attrs);
holder = getHolder();
x = (float) 0.0;
y = (float) 0.0;
scale = 1.0;
planet = BitmapFactory
.decodeResource(getResources(), R.drawable.planet);
sun = BitmapFactory.decodeResource(getResources(), R.drawable.sun);
}
// Functions
protected void setScale(int canvasWidth) {
// set liveMin and liveMax equal dist from edges
scale = (canvasWidth + sun.getWidth() / 2.0) / (liveMin + liveMax);
}
public void resetSurface() {
/*
* TODO: set up process for resetting the surface (recalc habitable
* zone, etc.)
*/
}
@Override
public boolean onTouch(View view, MotionEvent event) {
x = event.getX();
y = event.getY();
return true; // Allows dragging
}
public void pause() {
isRunning = false;
while (true) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
thread = null;
}
public void resume() {
isRunning = true;
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
while (isRunning) {
if (!holder.getSurface().isValid())
continue;
Canvas canvas = holder.lockCanvas();
// Calculate
setScale(canvas.getWidth());
// Draw
canvas.drawRGB(0, 0, 255);
paint.setColor(Color.rgb(50, 200, 0));
canvas.drawCircle(0, canvas.getHeight() / 2,
(float) (liveMax * scale), paint);
paint.setColor(Color.rgb(255, 50, 0));
canvas.drawCircle(0, canvas.getHeight() / 2,
(float) (liveMin * scale), paint);
// TODO: draw text for liveMin and liveMax
canvas.drawBitmap(sun, -sun.getWidth() / 2, canvas.getHeight() / 2
- sun.getHeight() / 2, null);
canvas.drawBitmap(planet, x - planet.getWidth() / 2,
y - planet.getHeight() / 2, null);
// TODO: draw text for T and r
// Display
holder.unlockCanvasAndPost(canvas);
}
}
}
如果有帮助,这里是布局XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".HabitableActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phase" />
<Spinner
android:id="@+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Albedo:" />
<SeekBar
android:id="@+id/seekBar2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tau" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<com.example.habitable.Surface
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
修改
这是堆栈跟踪:
02-21 00:20:09.425: D/dalvikvm(6782): GC_FOR_ALLOC freed 165K, 5% free 7514K/7832K, paused 14ms, total 14ms
02-21 00:20:09.475: D/dalvikvm(6782): GC_FOR_ALLOC freed 1K, 4% free 7766K/8088K, paused 17ms, total 18ms
02-21 00:20:09.555: D/dalvikvm(6782): GC_CONCURRENT freed 296K, 7% free 7885K/8408K, paused 4ms+3ms, total 25ms
02-21 00:20:09.555: D/dalvikvm(6782): WAIT_FOR_CONCURRENT_GC blocked 15ms
02-21 00:20:09.625: D/dalvikvm(6782): GC_FOR_ALLOC freed 65K, 4% free 8073K/8408K, paused 26ms, total 26ms
02-21 00:20:09.625: D/AndroidRuntime(6782): Shutting down VM
02-21 00:20:09.625: W/dalvikvm(6782): threadid=1: thread exiting with uncaught exception (group=0x4173e930)
02-21 00:20:09.635: E/AndroidRuntime(6782): FATAL EXCEPTION: main
02-21 00:20:09.635: E/AndroidRuntime(6782): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.habitable/com.example.habitable.HabitableActivity}: java.lang.NullPointerException
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.os.Handler.dispatchMessage(Handler.java:99)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.os.Looper.loop(Looper.java:137)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.ActivityThread.main(ActivityThread.java:5039)
02-21 00:20:09.635: E/AndroidRuntime(6782): at java.lang.reflect.Method.invokeNative(Native Method)
02-21 00:20:09.635: E/AndroidRuntime(6782): at java.lang.reflect.Method.invoke(Method.java:511)
02-21 00:20:09.635: E/AndroidRuntime(6782): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-21 00:20:09.635: E/AndroidRuntime(6782): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-21 00:20:09.635: E/AndroidRuntime(6782): at dalvik.system.NativeStart.main(Native Method)
02-21 00:20:09.635: E/AndroidRuntime(6782): Caused by: java.lang.NullPointerException
02-21 00:20:09.635: E/AndroidRuntime(6782): at com.example.habitable.HabitableActivity.onCreate(HabitableActivity.java:47)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.Activity.performCreate(Activity.java:5104)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-21 00:20:09.635: E/AndroidRuntime(6782): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
02-21 00:20:09.635: E/AndroidRuntime(6782): ... 11 more
答案 0 :(得分:2)
我认为您应该在致电setContentView(R.layout.activity_habitable);
后立即移动super.onCreate(savedInstanceState);
,因为现在这一行:
surface = (Surface) findViewById(R.id.surface);
导致表面为空。它找不到R.id.surface,因为你还没有设置内容视图而且你的布局没有膨胀。