我有一个地图活动,用于以全屏模式显示地图:
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);
}
}
}
}
}
}
现在,我想使用同一个类在SurfaceView元素中的其他活动中显示我的地图。因此,我尝试在一个新的Activity中使用SurfaceView元素,如下所示:
....
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);
这会导致nullpointer异常,因为canvas是null。在全屏模式下,我没有错误。 我的错是什么?
解决此类问题的常用方法如何?
答案 0 :(得分:1)
好的,最后我自己得到了答案:)以下是解决方案:
包含SurfaceView元素的活动必须移交SurfaceHolder
SurfaceView surface = (SurfaceView) findViewById(R.id.surfaceView1);
SurfaceHolder surfaceHolder = surface.getHolder();
Panel panel = new Panel(this,surfaceHolder);
表面类必须在其构造函数中初始化曲面,并且线程将在创建曲面时启动。
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
public Panel(Context context, SurfaceHolder surfaceHolder) {
super(context);
surfaceHolder.addCallback(this);
}
// start thread
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
// initiate new thread for drawing
_thread = new CanvasThread(surfaceHolder, this);
_thread.setRunning(true);
_thread.start();
}
// start drawing objects on canvas
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
/* several canvas operations ...
*/
}
// Thread specific class
class CanvasThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public 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);
}
}
}
}
}
}
这对我有用,但我决定将类Panel从MapActivity类中分离出来(在我的问题中显示)