Android lyrics show design ideas (1) SafetyTimer

Source: Internet
Author: User

When using Timer in Android, you need to access TimerTask, Handle, and other classes at the same time. The procedures are complicated and the things you really want to do are drowned in the procedural code. This document introduces the SafetyTimer class, which hides TimerTask and Handle classes and provides a simple and low-coupling implementation mode through the Observer design mode.
First, let's take a look at the location of SafetyTimer in the entire software.

It's a bit biased, but it doesn't matter.
Let's start.
There are many examples on the Internet about how to use Android timers. This is generally the case.
Public class TestTimerextends Activity {
Timer timer = new Timer ();
Handler handler = new Handler (){
Public void handleMessage (Message msg ){
Switch (msg. what ){
Case 1:
SetTitle ("hear me? "); // Here is what to do.
Break;
}
Super. handleMessage (msg );
}
};
TimerTask task = new TimerTask (){
Public void run (){
Message message = new Message ();
Message. what = 1;
Handler. sendMessage (message );
}
};
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );
Timer. schedule (task, 10000); // start the timer
}
}
The reason for this problem is that the run method of TimerTask is executed in an independent Task, and our use is not in the same context, therefore, we cannot directly execute the code we want to execute on a regular basis in the run method of TimerTask.
As one of the solutions to this problem, the Handler class is introduced, which is called by TimerTask first. sendMessage (multi-task Security) sends messages to Handler (in this place, all messages can be sent). Android can ensure that the messages are sent to Handler. handleMessage is already in the same context as the application.
The following are references
Timer: http://developer.android.com/reference/java/util/Timer.html
TimerTask: http://developer.android.com/reference/java/util/TimerTask.html
Handler: http://developer.android.com/reference/android/ OS /Handler.html
It looks so tired that it is not easy to find what we really want to do. But I have to watch it again. Is there a way to make this thing more beautiful.
Method 1: Use class inheritance
First, write the following base class. Basically, the code in the example is the same, but the OnTimer method that defines NO content is left for the implementation of the derived class.
Public class TemplateMethodTimer {
Private Timer mTimer = null;
Private Handler mHandler = null;
Private TimerTask mTask = null;

// TemplateMethod interface definition. The specific actions include Derived classes.
Public void OnTimer (){

}

// Start the timer
Public void startTimer (long interval ){
MHandler = new Handler (){
Public void handleMessage (Message msg ){
OnTimer (); // call the template method.
Super. handleMessage (msg );
}
};
MTask = new TimerTask (){
Public void run (){
Message message = new Message ();
Message. what = 0; // anything is OK.
MHandler. sendMessage (message );
}
};
MTimer = new Timer ();
MTimer. schedule (mTask, 0, interval );
}

// Stop the Timer action
// Release the obtained resources.
Public void stopTimer (){
MTimer. cancel ();
MTimer. purge ();
MTimer = null;
MHandler = null;
MTask = null;
}
}
With this class, we can first define a derived class and provide the Implementation of The OnTimer method.
Class MyTimer extends TemplateMethodTimer {
Public void OnTimer (){
Log. I (TAG, "MyTimer. OnTimer ");
}
}
Create a timer and start and stop the timer.
MyTimer Mt = new MyTimer ();
Mt. startTimer (500 );
Mt. stopTimer ();
Of course, in JAVA, we can create Timer as follows:
TemplateMethodTimer mTt = new TemplateMethodTimer (){
Public void OnTimer (){
Log. I (TAG, "TestTimer. OnTimer ");
}
};
Essentially the same code.
Method 2: Use the Observer design mode of the class. In this case, the Timer class is like this.
Public class ObserverTimer {
Private Timer mTimer = null;
Private Handler mHandler = null;
Private TimerTask mTask = null;
Private OnTimeListener mListener = null;
Private static final String TAG = new String ("SafetyTimer ");

// Observer Interface Definition
Public interface OnTimeListener {
Public void OnTimer ();
}

// Create a timer and specify the Observer
Public void setListener (OnTimeListener listener ){
MListener = listener;
}

// Start the timer
Public void startTimer (int interval ){
MHandler = new Handler (){
Public void handleMessage (Message msg ){
If (mListener! = Null ){
MListener. OnTimer ();
Log. I (TAG, "mListener. OnTimer ()");
}
Super. handleMessage (msg );
}
};
MTask = new TimerTask (){
Public void run (){
Message message = new Message ();
Message. what = 0; // anything is OK.
MHandler. sendMessage (message );
}
};
MTimer = new Timer ();
MTimer. schedule (mTask, 0, interval );
}

// Stop the Timer action
// Release the obtained resources.
Public void stopTimer (){
MTimer. cancel ();
MTimer. purge ();
MTimer = null;
MHandler = null;
MTask = null;
Log. I (TAG, "stopTimer ()");
}
}
The difference between this code and method 1 is that.
1. No method is defined for overwriting, but an OnTimerListener class is defined.
2. added the OnTimerListener data member mListener and provided the interface for setting it.
3. In Handler message processing, the set mListener. OnTimer () is called instead of calling its own method (and not ()
 
With this ObserverTimer class, we can create and use Timer as follows.
 
ObserverTimer mOt = new ObserverTimer ();
MOt. setListener (new ObserverTimer. OnTimeListener (){
@ Override
Public void OnTimer (){
Log. I (TAG, "ObserverTimer. OnTimer ");
}
});
MOt. startTimer (1000 );
MOt. stopTimer ();
Is it much better. Such code is everywhere in Android. The key is whether the code we made will be made like this.
It seems that there is little difference in usage. which method is better?
Method 1 defines a base class that does not know what to do, and then implements a Timer that does something. Timer is abstracted.
Method 2 is a Listener base class that specifically responds to Timer. It implements specific functions through the derived class of Listener. Abstract what to do should be closer to the essence. From the utilitarian point of view, we can see that Listener can be dynamically logged on and deleted, which is more flexible. Of course, not to mention that if you slightly modify Obersever, You can implement multiple objects to respond to Timer events.
It's self-evident.
Through this article, we can see that complicated Timer processing methods are hidden through Observer design mode encapsulation. In this way, the next person who uses Timer does not have to take the path that others have already taken and spend the time saved on other challenges. There is no difficulty in doing so, but I am afraid it will not be much in practice. In any case, please believe that this seemingly insignificant step will fundamentally change our program structure.
The SaftyTimer class used in the Android lyrics show is implemented in method 2 for reference.

We use SaftyTimer to encapsulate the gray Timer, TimerTask, and Handler functions, and then define SaftyTimer: OnTimeListener to provide the caller with the required functions.
The following figure shows the sequence.

We can clearly see that in the call starting from LayerPlayerService, except the two lines that generate the new object, there are only three lines: StartTimer, OnTimer, and StopTimer. The call to the right of SaftyTimer is much more complicated. This is the encapsulation effect.
Source code

Package LyricPlayer. xwg;
 
Import java. util. Timer;
Import java. util. TimerTask;
 
Import android. OS. Handler;
Import android. OS. Message;
Import android. util. Log;
 
Public class SafetyTimer {
Private Timer mTimer = null;
Private Handler mHandler = null;
Private TimerTask mTask = null;
Private OnTimeListener mListener = null;
Private long mInterval = 0; // in milliseconds
Private static final String TAG = new String ("SafetyTimer ");

// Observer Interface Definition
Public interface OnTimeListener {
Public void OnTimer ();
}

// Create a timer and specify the Observer
Public SafetyTimer (long interval, OnTimeListener listener ){
MInterval = interval;
MListener = listener;
}

// Start the timer
Public void startTimer (){
MHandler = new Handler (){
Public void handleMessage (Message msg ){
If (mListener! = Null ){
MListener. OnTimer ();
Log. I (TAG, "mListener. OnTimer ()");
}
Super. handleMessage (msg );
}
};
MTask = new TimerTask (){
Public void run (){
Message message = new Message ();
Message. what = 0; // anything is OK.
MHandler. sendMessage (message );
}
};
MTimer = new Timer ();
MTimer. schedule (mTask, 0, mInterval );
}

// Stop the Timer action
// Release the obtained resources.
Public void stopTimer (){
MTimer. cancel ();
MTimer. purge ();
MTimer = null;
MHandler = null;
MTask = null;
Log. I (TAG, "stopTimer ()");
}

// Whether the Timer is in the working state.
Public boolean isRunging (){
Return (mTimer! = Null );
}
}


Author: "From Dalian"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.