package org.bitseal.controllers;
import org.bitseal.core.App;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
/**
* A Singleton class that provides a thread to process newly
* downloaded messages.
*
* @author JonathanCoe
*/
public class MessageProcessingThread
{
private Thread processingThread;
/** A key used to store the time of the last successful 'check for new msgs' server request */
private static final String LAST_MSG_CHECK_TIME = "lastMsgCheckTime";
/** Stores the Unix timestamp of the last msg payload we processed. This can be used to tell us how far behind the network we are. */
private static final String LAST_PROCESSED_MSG_TIME = "lastProcessedMsgTime";
private static final String TAG = "MESSAGE_PROCESSING_THREAD";
private static class Holder
{
static MessageProcessingThread INSTANCE = new MessageProcessingThread();
}
/**
* Returns a singleton instance of the MessageProcessingThread. This ensures that
* only one instance of the thread will ever be exist at once.
*/
protected static MessageProcessingThread getInstance()
{
return Holder.INSTANCE;
}
/**
* Starts the thread for processing new messages, in such a way that the
* thread will only be started if it is not already running.
*/
protected void startThread()
{
if (processingThread.getState() == Thread.State.NEW) // The thread has not been started yet
{
processingThread.start();
}
else if (processingThread.getState() == Thread.State.TERMINATED) // The thread has run to completion
{
setNewThreadInstance();
MessageProcessingThread.getInstance().startThread();
}
else
{
Log.d(TAG, "MessageProcessingThread.startThread() was called, but the thread is already running.");
}
}
/**
* Creates a new MessageProcessingThread instance and sets the
* static INSTANCE variable to point to it.
*/
private void setNewThreadInstance()
{
Holder.INSTANCE = new MessageProcessingThread();
}
private MessageProcessingThread()
{
// Create a thread for processing the messages we download
processingThread = new Thread(new Runnable()
{
@Override
public void run()
{
try
{
Log.i(TAG, "Starting message processing thread.");
CheckForMessagesController controller = new CheckForMessagesController();
int newMessagesProcessed = controller.processIncomingMessages();
while (newMessagesProcessed > 0)
{
newMessagesProcessed = controller.processIncomingMessages();
}
// Once we have processed the last available new msg, update the 'last processed msg' time to equal the
// 'last msg check' time
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(App.getContext());
SharedPreferences.Editor editor = prefs.edit();
long lastMsgCheckTime = prefs.getLong(LAST_MSG_CHECK_TIME, 0);
editor.putLong(LAST_PROCESSED_MSG_TIME, lastMsgCheckTime);
editor.commit();
Log.i(TAG, "Updated the 'last processed msg time' value stored in SharedPreferences to " + lastMsgCheckTime);
// Attempt to send any pending acknowledgements
controller.sendAcknowledgments();
Log.i(TAG, "Finishing message processing thread.");
}
catch (Exception e)
{
Log.e(TAG, "While running MessageProcessingThread(), processingThread.run() threw an Execption. \n" +
"The exception message was: " + e.getMessage());
}
}
});
}
}