2009-03-23 58 views
5

Tôi hiện đang nắm bắt được Android, chơi xung quanh với mẫu Lunar Lander.Android: Lấy lại tiêu điểm bằng SurfaceView

Tôi thấy rằng nếu bạn điều hướng khỏi ứng dụng (ví dụ: nhấn nút gọi), nó sẽ phá hủy bề mặt cơ bản (gọi surfaceDestroyed).

Điều hướng trở lại (sẽ kích hoạt onWindowVisibilityChanged) ứng dụng sẽ gặp sự cố, vì ứng dụng sẽ cố gắng vẽ lên bề mặt mà không cần tạo lại.

Có một số mã tôi có thể đặt trong onWindowVisibilityChanged (hoặc bất kỳ nơi nào khác) mà sẽ tạo lại bề mặt cơ bản của SurfaceView và tiếp tục thực hiện độc đáo không?

Có vẻ như đây chỉ là một cuộc gọi hàm đơn giản nhưng tôi không thể tìm thấy bất kỳ thứ gì trong tài liệu API.

Cảm ơn!

Trả lời

1

Chẩn đoán sai! Ứng dụng tự động tạo lại bề mặt, nhưng có một cuộc gọi trong đó cố gắng vẽ lên bề mặt đó trước khi nó được tạo.

Sửa vấn đề:

boolean mSurfaceExists; 
... 
public void surfaceDestroyed(SurfaceHolder holder) { 
    mSurfaceExists = false; 
    ... 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    mSurfaceExists = true; 
    ... 
} 

protected void onWindowVisibilityChanged(int visibility) { 
    // only call base if there's a surface 
    if(mSurfaceExists) 
     super.onWindowVisibilityChanged(visibility); 
} 

Bây giờ nó là tất cả sưng. (theo như tôi biết, dù sao - các chuyên gia Java/Android cảm thấy tự do để nhận xét nếu đây là thực hành không tốt!)

+0

Tôi đã thử điều này và nó không vẽ trò chơi lander mặt trăng đúng cách. Tất cả bạn nhận được là văn bản không phải là tàu không gian hoặc nền. –

2

Giải pháp này cho "mSurfaceExists = true" cũng không hoạt động đối với tôi. Có vẻ như surfaceCreated() không được gọi vì super.onWindowVisibilityChanged() không được gọi. Vì vậy, không có bề mặt được tạo ra và nó không sụp đổ vì threas.start không được gọi.

Tôi tin rằng vấn đề là: Gọi thread.start() gây ra lỗi vì chuỗi đã được bắt đầu. Nhưng trong bề mặtDestroyed(), thread.join làm cho luồng hoàn thành và chết. Và một thread không thể khởi động lại khi đã chết.

Tôi đoán mẹo là tạo một chuỗi mới trong surfacecreated hoặc chỉ gây ra thread hoàn thành khi người dùng đang gọi ứng dụng để kết thúc (phím quay lại) và không tạm dừng (phím home). Điều này có thể được kiểm tra bằng cách gọi isFinishing() trên hoạt động.

Không chắc chắn điều này có hiệu quả hay không. Tôi sẽ cố gắng sớm thôi.

+0

Chỉ cần thử nghiệm (sửa lỗi) và nó là, như bạn nghĩ. 'surfaceDestroyed()' được gọi ngay sau khi ứng dụng bị ẩn và luồng được dừng lại. Khi hiển thị lại ứng dụng, 'surfaceCreated()' được gọi và cố gắng khởi động lại luồng, kết quả là một 'IllegalThreadStateException'. – Ridcully

Các vấn đề liên quan