Android 成员访问上的SurfaceView NullPointerException
我正在尝试创建一个程序,该程序接受太阳和行星的某些参数,并在扩展的SurfaceView类曲面中渲染可居住区域。我可以让它运行,只要我不尝试从主活动类访问曲面的任何成员,但曲面不显示。当我试图访问一个成员时,程序崩溃,我得到一个NullPointerException 以下是HabitalActivity.java(主要活动)的相关部分: 和Surface.java:Android 成员访问上的SurfaceView NullPointerException,android,nullpointerexception,surfaceview,Android,Nullpointerexception,Surfaceview,我正在尝试创建一个程序,该程序接受太阳和行星的某些参数,并在扩展的SurfaceView类曲面中渲染可居住区域。我可以让它运行,只要我不尝试从主活动类访问曲面的任何成员,但曲面不显示。当我试图访问一个成员时,程序崩溃,我得到一个NullPointerException 以下是HabitalActivity.java(主要活动)的相关部分: 和Surface.java: public class Surface extends SurfaceView implements Runnable, On
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>
我认为你应该移动
setContentView(R.layout.activity\u habitable)调用super.onCreate(savedInstanceState)后立即调用code>代码>因为现在这行:
surface = (Surface) findViewById(R.id.surface);
导致该曲面为空。它找不到R.id.surface,因为您尚未设置内容视图,并且布局未膨胀。我认为您应该移动设置内容视图(R.layout.activity\u habitable)调用super.onCreate(savedInstanceState)后立即调用code>代码>因为现在这行:
surface = (Surface) findViewById(R.id.surface);
导致该曲面为空。它找不到R.id.surface,因为您还没有设置内容视图,而且布局也没有膨胀。@Ruckus,您犯了一个愚蠢的错误,请参阅Michal的Answer@Ruckus,你犯了一个愚蠢的错误,请看迈克尔的回答谢谢。我一直在做这样的事情。通常我会抓到它。它没有显示或者你的线程没有启动?你在什么地方调用start()了吗?是的,在resume()方法中,它是从resume()的主要活动中调用的。我想出来了。我将线性布局在曲面上方的高度设置为匹配父对象而不是包裹内容。谢谢。我一直在做这样的事情。通常我会抓到它。它没有显示或者你的线程没有启动?你在什么地方调用start()了吗?是的,在resume()方法中,它是从resume()的主要活动中调用的。我想出来了。我将LinearLayout在曲面上方的高度设置为匹配父对象而不是包裹内容。
surface = (Surface) findViewById(R.id.surface);