0

我正在尝试创建一个程序,该程序接受太阳和行星的某些参数,并在扩展的 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
4

1 回答 1

3

我认为你应该setContentView(R.layout.activity_habitable);在你打电话后立即移动,super.onCreate(savedInstanceState);因为现在这条线:

surface = (Surface) findViewById(R.id.surface);

导致该表面为空。它找不到 R.id.surface 因为您还没有设置内容视图并且您的布局没有膨胀。

于 2013-02-21T07:17:46.017 回答