I have an map activity for displaying a map in fullscreen mode:
public class MapActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new Panel(this));
}
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
// initiate new thread for drawing
_thread = new CanvasThread(getHolder(), this);
}
// start thread
@Override
public void surfaceCreated(SurfaceHolder holder) {
CanvasThread.setRunning(true);
_thread.start();
}
// start drawing objects on canvas
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
/* several canvas operations ...
*/
}
// Thread specific class
static class CanvasThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private static boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public static void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas c;
Log.d("Thread", "start");
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
Log.d("Thread", "Canvas c init");
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
Now, I’d like to use the same class to display my map in an other activity within an SurfaceView Element. Therefore I tried to take SurfaceView Element in a new Activity as follows:
....
Panel surface = new KarteActivity().new Panel(this);
surface._thread.start();
CanvasThread.setRunning(true);
LinearLayout midLL = new LinearLayout(this);
midLL.findViewById(R.id.surfaceView1);
midLL.addView(surface);
This causes a nullpointer exception because the canvas is null. In fullscreen mode I have no errors.
What is my mistake?
How is the usual way to solve such problem?
Ok, finally I got the answer on my own 🙂 Here is the solution:
The activity which contains the SurfaceView element has to hand over the SurfaceHolder
The surface class has to initialize the surface in its contructor and the thread will start when the surface is created.
This worked for me but I decided to seperate the class Panel out of the class MapActivity (shown in my question)