tôi sử dụng chiến lược này, đầu tiên tôi tuyên bố một Handler và Runnable như vậy:
private final Observable mObservable = new Observable();
private final static int TIME_STEP_MS = 5;
private final Handler mHandler = new Handler();
private final Runnable mTimeManager = new Runnable()
{
public void run()
{
mObservable.notifyObservers(TIME_STEP_MS);
mHandler.postDelayed(mTimeManager, TIME_STEP_MS);
}
};
Sau đó, khi tôi muốn bắt đầu quản lý thời gian của tôi, tôi chỉ cần gọi mTimeManager.run() và nó sẽ bắt đầu thông báo cho tôi Observer
s (được thêm trước) định kỳ.
Nếu bạn cần cho một số lý do ngừng đồng hồ đếm hoặc một cái gì đó bạn chỉ cần làm điều đó:
mHandler.removeCallbacks(mTimeManager);
[EDIT - hoàn More code]
Ok hơn chúng ta hãy làm cho nó rõ ràng hơn, đầu tiên tôi làm một đối tượng tùy chỉnh có thể quan sát được như vậy [tùy chọn]:
private final Observable mObservable = new Observable()
{
public void notifyObservers()
{
setChanged();
super.notifyObservers();
};
@Override
public void notifyObservers(Object data)
{
setChanged();
super.notifyObservers(data);
};
};
lý do là vì tôi không thể gọi setChan ged() bên ngoài lớp quan sát được - nó được bảo vệ, nếu nó không thay đổi, nó không thông báo cho bất kỳ người quan sát nào.
Các khai báo khác giữ nguyên như trước, bây giờ tôi cần bắt đầu TimeManager
ở đâu đó, ứng dụng của tôi là LiveWallpaper và tôi làm mọi thứ hiển thị thành lớp mở rộng Thread
nhưng bạn không nhất thiết phải tôi đã thực hiện một phương pháp gọi là resumeDrawing()
, chương trình này được gọi là ngay sau khi super.start();
tại @Override
của tôi về public synchronized void start()
từ Thread
lớp, phương pháp này trông như thế:
public void resumeDrawing()
{
if (!mTimeManagerRunning) // just a boolean field in my class
{
System.err.println("Resuming renderer."); // just for debug
mTimeManager.run();
mTimeManagerRunning = true;
}
else
{
System.err.println("Renderer already running."); // just for debug
}
}
và nó kép:
public void pauseDrawing()
{
if (mTimeManagerRunning)
{
System.err.println("Pausing renderer.");
mHandler.removeCallbacks(mTimeManager);
mTimeManagerRunning = false;
}
else
{
System.err.println("Renderer already paused.");
}
}
Ok, bây giờ chúng ta có thể bắt đầu và ngừng quản lý thời gian, nhưng ai đang lắng nghe? Không ai!vì vậy hãy add'em: Trên constructor của Renderer tôi thêm một số Observer
s đến đối tượng mObservable
của tôi, một trong những là Renderer bản thân, vì vậy renderer của tôi kéo dài Thread
và thực hiện Observer
:
@Override // from Observer interface
public void update(Observable arg0, Object arg1)
{
mElapsedMsRedraw += (Integer) arg1;
if (mElapsedMsRedraw >= mDrawingMsPerFrame)
{
mElapsedMsRedraw = 0;
drawEm(); // refresh the canvas and stuff
}
}
để thêm các nhà quan sát bạn chỉ cần làm mObservable.addObserver(THE_OBJECT - Implements Observer)
bạn có thể thấy rằng tôi không hiển thị lại nội dung của mình mỗi khi tôi được thông báo, đó là vì tôi sử dụng TimeManager này cho các suy nghĩ khác ngoài việc làm mới Canvas
như cập nhật vị trí của đối tượng tôi muốn để vẽ chỉ trong nội bộ. Vì vậy, những gì bạn cần để làm chậm bản vẽ là thay đổi cách đối tượng của bạn thay đổi nội bộ trong khi thời gian trôi qua, tôi có nghĩa là vòng tròn và điểm của bạn, hoặc bạn có thể cơ hội bước thời gian của bạn, tôi khuyên bạn nên đầu tiên.
Có rõ ràng hơn không? Tôi hy vọng nó sẽ giúp.
thx, nhưng bạn có thể đăng một ví dụ hoàn chỉnh hơn không? Đang hiển thị việc triển khai. – FooBar
Chắc chắn, tôi đang làm việc bây giờ đó là đoạn mã tôi có thể nhớ. Tôi sẽ rời đi trong 20 phút để ASAP tôi sẽ cung cấp cho bạn một mã hoàn chỉnh hơn. – HericDenis
Ok @FooBar bây giờ tôi về nhà, tôi sẽ giúp bạn (: – HericDenis