我试图将我的程序的两个部分放在一起。我有一张地图,用户可以四处移动并点击地图的某些部分。然后它将它们带到一个新的活动,显示他们按下的信息。显示信息时出现错误。它启动活动并暂时显示它,但随后重新启动MainActivity。错误似乎出现在我的SurfaceView类中。
public class MapSurface extends SurfaceView implements SurfaceHolder.Callback {
private static MapSurface rs;
private Context c;
private SurfaceHolder sh;
private RenderSurfaceThread render_thread;
private static Map map;
public MapSurface(Context context, AttributeSet attr) {
super(context, attr);
c = context;
sh = getHolder();
sh.addCallback(this);
render_thread = new RenderSurfaceThread();
setFocusable(true);
}
public static MapSurface getInstance() {
return rs;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
rs = this;
map = new Map(c.getResources(), R.drawable.map, getWidth(), getHeight());
render_thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
render_thread.stopThread();
}
@Override
public boolean onTouchEvent(MotionEvent e) {
return MapTouchHandler.handleTouch(this, map, e);
}
public final Map getMap() {
return map;
}
public void requestRedraw() {
render_thread.throttleThread();
}
public int getState() {
return render_thread.thread_state;
}
public RenderSurfaceThread getThread() {
return render_thread;
}
class RenderSurfaceThread extends Thread {
// Some thread state variables.
public static final int THREAD_UNDEFINED = -1;
public static final int THREAD_NEW = 0;
public static final int THREAD_IDLE = 1;
public static final int THREAD_EXECUTING = 2;
public static final int THREAD_KILL = 3;
public static final int THREAD_DEAD = 4;
// Thread state variable.
private int thread_state = THREAD_UNDEFINED;
// Idle lock object
private final Object RUN_LOCK = new Object();
private RenderSurfaceThread() {
setState(THREAD_NEW);
}
@Override
public void run() {
setState(THREAD_EXECUTING);
while (thread_state != THREAD_KILL) {
map.transformImage();
doDraw();
// Thread will idle until redraw is requested.
idleThread();
}
setState(THREAD_DEAD);
}
private void doDraw() {
Canvas canvas = null;
try {
canvas = sh.lockCanvas(null);
synchronized (sh) {
// Critical section. Do not allow mRun to be set false until
// we are sure all canvas draw operations are complete.
//
// If mRun has been toggled false, inhibit canvas
// operations.
synchronized (RUN_LOCK) {
if (thread_state == THREAD_EXECUTING) {
// Do our drawing here
canvas.drawBitmap(map.getMapBitmap(), 0, 0, null);
}
}
}
} 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 (canvas != null) {
sh.unlockCanvasAndPost(canvas);
}
}
}
private void idleThread() {
setState(THREAD_IDLE);
try {
do {
synchronized (sh) {
sh.wait();
}
} while (thread_state != THREAD_EXECUTING); // Ensure the notify
// means that it is
// time to execute
// and not something else
} catch (InterruptedException e) {
}
}
private void throttleThread() {
synchronized (sh) {
setState(THREAD_EXECUTING);
sh.notifyAll();
}
}
private void setState(int state) {
synchronized (sh) {
synchronized (RUN_LOCK) {
assert (thread_state != THREAD_DEAD);
thread_state = state;
RUN_LOCK.notifyAll();
}
}
}
private void stopThread() {
// we have to tell thread to shut down & wait for it to finish, or
// else
// it might touch the Surface after we return and explode
boolean retry = true;
do {
if (thread_state == THREAD_IDLE) {
setState(THREAD_KILL);
throttleThread();
} else {
try {
RUN_LOCK.wait();
} catch (Exception e) {
}
}
} while (thread_state != THREAD_KILL
&& thread_state != THREAD_DEAD);
while (retry) {
try {
join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
}
Logcat输出:
12-07 00:16:18.235: E/AndroidRuntime(2721): FATAL EXCEPTION: main
12-07 00:16:18.235: E/AndroidRuntime(2721): java.lang.IllegalMonitorStateException: object not locked by thread before wait()
12-07 00:16:18.235: E/AndroidRuntime(2721): at java.lang.Object.wait(Native Method)
12-07 00:16:18.235: E/AndroidRuntime(2721): at java.lang.Object.wait(Object.java:364)
12-07 00:16:18.235: E/AndroidRuntime(2721): at com.eecs448.kuville.ui.MapSurface$RenderSurfaceThread.stopThread(MapSurface.java:183)
12-07 00:16:18.235: E/AndroidRuntime(2721): at com.eecs448.kuville.ui.MapSurface$RenderSurfaceThread.access$1(MapSurface.java:171)
12-07 00:16:18.235: E/AndroidRuntime(2721): at com.eecs448.kuville.ui.MapSurface.surfaceDestroyed(MapSurface.java:53)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.SurfaceView.updateWindow(SurfaceView.java:555)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:232)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.View.dispatchWindowVisibilityChanged(View.java:7682)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1227)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.Choreographer.doCallbacks(Choreographer.java:562)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.Choreographer.doFrame(Choreographer.java:532)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.os.Handler.handleCallback(Handler.java:730)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.os.Handler.dispatchMessage(Handler.java:92)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.os.Looper.loop(Looper.java:137)
12-07 00:16:18.235: E/AndroidRuntime(2721): at android.app.ActivityThread.main(ActivityThread.java:5103)
12-07 00:16:18.235: E/AndroidRuntime(2721): at java.lang.reflect.Method.invokeNative(Native Method)
12-07 00:16:18.235: E/AndroidRuntime(2721): at java.lang.reflect.Method.invoke(Method.java:525)
12-07 00:16:18.235: E/AndroidRuntime(2721): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
12-07 00:16:18.235: E/AndroidRuntime(2721): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-07 00:16:18.235: E/AndroidRuntime(2721): at dalvik.system.NativeStart.main(Native Method)
12-07 00:16:18.285: E/InputDispatcher(1201): channel 'b1404ba8 com.eecs448.kuville/com.eecs448.kuville.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
12-07 00:16:18.285: E/InputDispatcher(1201): channel 'b15a72b8 com.eecs448.kuville/com.eecs448.kuville.Building (server)' ~ Channel is unrecoverably broken and will be disposed!
12-07 00:16:18.285: E/InputDispatcher(1201): channel 'b158bbf8 com.eecs448.kuville/com.eecs448.kuville.main.MapActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
12-07 00:16:18.335: E/JavaBinder(1201): *** Uncaught remote exception! (Exceptions are not yet supported across processes.)
12-07 00:16:18.335: E/JavaBinder(1201): java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
12-07 00:16:18.335: E/JavaBinder(1201): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
12-07 00:16:18.335: E/JavaBinder(1201): at java.util.ArrayList.get(ArrayList.java:308)
12-07 00:16:18.335: E/JavaBinder(1201): at com.android.server.am.ActivityManagerService.handleAppCrashLocked(ActivityManagerService.java:8351)
12-07 00:16:18.335: E/JavaBinder(1201): at com.android.server.am.ActivityManagerService.makeAppCrashingLocked(ActivityManagerService.java:8221)
12-07 00:16:18.335: E/JavaBinder(1201): at com.android.server.am.ActivityManagerService.crashApplication(ActivityManagerService.java:8900)
12-07 00:16:18.335: E/JavaBinder(1201): at com.android.server.am.ActivityManagerService.handleApplicationCrashInner(ActivityManagerService.java:8455)
12-07 00:16:18.335: E/JavaBinder(1201): at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:8437)
12-07 00:16:18.335: E/JavaBinder(1201): at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:1211)
12-07 00:16:18.335: E/JavaBinder(1201): at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:1737)
12-07 00:16:18.335: E/JavaBinder(1201): at android.os.Binder.execTransact(Binder.java:388)
12-07 00:16:18.335: E/JavaBinder(1201): at dalvik.system.NativeStart.run(Native Method)
12-07 00:16:18.335: E/ActivityManager(1201): Activity Manager Crash
12-07 00:16:18.335: E/ActivityManager(1201): java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
12-07 00:16:18.335: E/ActivityManager(1201): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
12-07 00:16:18.335: E/ActivityManager(1201): at java.util.ArrayList.get(ArrayList.java:308)
12-07 00:16:18.335: E/ActivityManager(1201): at com.android.server.am.ActivityManagerService.handleAppCrashLocked(ActivityManagerService.java:8351)
12-07 00:16:18.335: E/ActivityManager(1201): at com.android.server.am.ActivityManagerService.makeAppCrashingLocked(ActivityManagerService.java:8221)
12-07 00:16:18.335: E/ActivityManager(1201): at com.android.server.am.ActivityManagerService.crashApplication(ActivityManagerService.java:8900)
12-07 00:16:18.335: E/ActivityManager(1201): at com.android.server.am.ActivityManagerService.handleApplicationCrashInner(ActivityManagerService.java:8455)
12-07 00:16:18.335: E/ActivityManager(1201): at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:8437)
12-07 00:16:18.335: E/ActivityManager(1201): at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:1211)
12-07 00:16:18.335: E/ActivityManager(1201): at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:1737)
12-07 00:16:18.335: E/ActivityManager(1201): at android.os.Binder.execTransact(Binder.java:388)
12-07 00:16:18.335: E/ActivityManager(1201): at dalvik.system.NativeStart.run(Native Method)
答案 0 :(得分:0)
相反做这个MapSurface法术。为什么不选择Google Map v2。
https://developers.google.com/maps/documentation/android/
在其上添加任何类型的Marker并倾听他们的行动并做任何你想做的事。
地图是3d,地图部分就像魅力一样。
答案 1 :(得分:0)
确保你像这样处理onSaveInstanceState
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("inprogress", true);
super.onSaveInstanceState(outState);
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
boolean isNew = true;
if(savedInstanceState != null)
isNew = !savedInstanceState.getBoolean("inprogress");
initActivity(isNew);
}
您需要区分在应用开始时或保存配置后创建的主要活动