1

I've been doing a little learning from youtube about android custom views and all. In my attempt to do a Surface View (rather simple as described in this video).

I've done things pretty much in sync with what was shown in the video.

How ever I am receiving a null pointer exception in the surfaceHolder.getSurface() .

Here is my entire code :

import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MainActivity extends AppCompatActivity { Ui ui; Bitmap ball; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); ui = new Ui(this); ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball); setContentView(ui); } @Override protected void onResume() { super.onResume(); ui.resume(); } @Override protected void onPause() { super.onPause(); ui.pause(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } public class Ui extends SurfaceView implements Runnable { private Thread thread; private SurfaceHolder surfaceHolder; boolean ok = false; public Ui(Context context) { super(context); thread = null; surfaceHolder = getHolder(); } @Override public void run() { while (ok) { if (!surfaceHolder.getSurface().isValid()) { continue; } Canvas canvas = surfaceHolder.lockCanvas(); canvas.drawARGB(200, 150, 130, 120); canvas.drawBitmap(ball, 0, 0, null); surfaceHolder.unlockCanvasAndPost(canvas); } } public void pause() { ok = false; while (true) { try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } break; } thread = null; } public void resume() { ok = true; thread = new Thread(this); thread.run(); } } } 

This part of the code :

Some pointer to what I am doing wrong will be helpful!.

@Override public void run() { while (ok) { if (!surfaceHolder.getSurface().isValid()) { continue; } Canvas canvas = surfaceHolder.lockCanvas(); canvas.drawARGB(200, 150, 130, 120); canvas.drawBitmap(ball, 0, 0, null); surfaceHolder.unlockCanvasAndPost(canvas); } } 

The problem appears in this line :

if (!surfaceHolder.getSurface().isValid()) 

always returns false and the later part of the code is never executed.

Logcat :

06-25 15:23:46.211 2012-2012/com.pchakraverti.canvasapp D/AndroidRuntime﹕ Shutting down VM 06-25 15:23:46.211 2012-2012/com.pchakraverti.canvasapp W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xa62f8288) 06-25 15:23:46.211 2012-2012/com.pchakraverti.canvasapp E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity {com.pchakraverti.canvasapp/com.pchakraverti.canvasapp.MainActivity}: java.lang.NullPointerException at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089) at android.app.ActivityThread.access$600(ActivityThread.java:130) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at com.pchakraverti.canvasapp.Ui.run(Ui.java:44) at java.lang.Thread.run(Thread.java:856) at com.pchakraverti.canvasapp.Ui.resume(Ui.java:66) at com.pchakraverti.canvasapp.MainActivity.onPostResume(MainActivity.java:24) at android.app.Activity.performResume(Activity.java:5095) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)             at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)             at android.app.ActivityThread.access$600(ActivityThread.java:130)             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)             at android.os.Handler.dispatchMessage(Handler.java:99)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) 06-25 15:23:46.227 2012-2015/com.pchakraverti.canvasapp D/dalvikvm﹕ GC_CONCURRENT freed 208K, 3% free 10919K/11207K, paused 12ms+0ms, total 15ms 06-25 15:25:15.043 2067-2067/com.pchakraverti.canvasapp D/dalvikvm﹕ Late-enabling CheckJNI 06-25 15:25:15.091 2067-2070/com.pchakraverti.canvasapp D/dalvikvm﹕ GC_CONCURRENT freed 98K, 3% free 11074K/11335K, paused 11ms+0ms, total 23ms 06-25 15:25:15.095 2067-2067/com.pchakraverti.canvasapp D/dalvikvm﹕ GC_FOR_ALLOC freed <1K, 3% free 11073K/11335K, paused 4ms, total 4ms 06-25 15:25:15.131 2067-2067/com.pchakraverti.canvasapp I/dalvikvm-heap﹕ Grow heap (frag case) to 11.887MB for 1048588-byte allocation 06-25 15:25:15.155 2067-2070/com.pchakraverti.canvasapp D/dalvikvm﹕ GC_CONCURRENT freed 0K, 3% free 12097K/12423K, paused 15ms+0ms, total 22ms 06-25 15:25:15.155 2067-2067/com.pchakraverti.canvasapp D/dalvikvm﹕ WAIT_FOR_CONCURRENT_GC blocked 0ms 06-25 15:25:15.163 2067-2067/com.pchakraverti.canvasapp I/dalvikvm﹕ Could not find method android.view.ViewGroup.onRtlPropertiesChanged, referenced from method android.support.v7.widget.Toolbar.onRtlPropertiesChanged 06-25 15:25:15.163 2067-2067/com.pchakraverti.canvasapp W/dalvikvm﹕ VFY: unable to resolve virtual method 13337: Landroid/view/ViewGroup;.onRtlPropertiesChanged (I)V 06-25 15:25:15.163 2067-2067/com.pchakraverti.canvasapp D/dalvikvm﹕ VFY: replacing opcode 0x6f at 0x0007 06-25 15:25:15.163 2067-2067/com.pchakraverti.canvasapp I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.internal.widget.TintTypedArray.getChangingConfigurations 06-25 15:25:15.163 2067-2067/com.pchakraverti.canvasapp W/dalvikvm﹕ VFY: unable to resolve virtual method 408: Landroid/content/res/TypedArray;.getChangingConfigurations ()I 06-25 15:25:15.163 2067-2067/com.pchakraverti.canvasapp D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002 06-25 15:25:15.167 2067-2067/com.pchakraverti.canvasapp I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.internal.widget.TintTypedArray.getType 06-25 15:25:15.167 2067-2067/com.pchakraverti.canvasapp W/dalvikvm﹕ VFY: unable to resolve virtual method 430: Landroid/content/res/TypedArray;.getType (I)I 06-25 15:25:15.167 2067-2067/com.pchakraverti.canvasapp D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002 06-25 15:25:15.171 2067-2067/com.pchakraverti.canvasapp D/AndroidRuntime﹕ Shutting down VM 06-25 15:25:15.171 2067-2067/com.pchakraverti.canvasapp W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xa62f8288) 06-25 15:25:15.171 2067-2067/com.pchakraverti.canvasapp E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity {com.pchakraverti.canvasapp/com.pchakraverti.canvasapp.MainActivity}: java.lang.NullPointerException at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089) at android.app.ActivityThread.access$600(ActivityThread.java:130) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at com.pchakraverti.canvasapp.Ui.run(Ui.java:45) at java.lang.Thread.run(Thread.java:856) at com.pchakraverti.canvasapp.Ui.resume(Ui.java:66) at com.pchakraverti.canvasapp.MainActivity.onPostResume(MainActivity.java:24) at android.app.Activity.performResume(Activity.java:5095) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)             at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)             at android.app.ActivityThread.access$600(ActivityThread.java:130)             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)             at android.os.Handler.dispatchMessage(Handler.java:99)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) 06-25 15:26:56.039 2120-2125/com.pchakraverti.canvasapp I/dalvikvm﹕ threadid=3: reacting to signal 3 

2 Answers 2

1

please also look at this problem issued by myself, actually, it is very similar:
View.SurfaceView, why its member, mSurfaceHolder, returns null from getSurface()?
i also read the source code of SurfaceView.java in android sdk 22, but I noticed that member SurfaceView.mSurfaceHolder.getSurface() always returns null. That frastrates me!

Sign up to request clarification or add additional context in comments.

Comments

1

The SurfaceView has two parts, the Surface and the View. The Surface is created asynchronously, by the Window Manager, and you can't do anything with it until it's ready. You have to handle the SurfaceHolder.Callback methods to know when the Surface has been created and destroyed.

The SurfaceView lifecycle is not in lock step with the Activity life cycle, so you have to be a bit careful about allocating resources (like Camera) and starting / stopping threads. A discussion of the topic can be found in this appendix of the graphics architecture document. Various examples can be found in Grafika.

Please make sure that a SurfaceView is what you actually want. If you want a custom View, you should be working with View, not SurfaceView.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.