问题
Basically i am developing a rss feed for android, and i want to have a updater service that, for each source, get the feeds in specific time.
Imagine:
Source1 - 5minutes Source2 - 10minutes Source3 - 10minutes
I build a differential list to use only one thread that make the requests for update. The datastructure stays like this:
Source1 (next sleep - 5), Source2 (next sleep - 0, Source 3 (next sleep 5).. and so on..
What i do is, i add always to a list of providers (that contains the id and URL) and when sleep is != 0, i order the update (that uses async task, i pass the list of providers to update, and asynctask do the job for me, that is... go to internet, parse content, and update database)
but exists one worker thread that is sleeping just for the sake of group a bundle of providers and sent to AsyncTask to update.
What's the problem.. First the thread don't sleep for the specific time, the thread must sleep 10 minutes, i made a method for convert minutes to milis, that is:
private static int MinutesToMilis(int minutes) { return minutes * 1000 * 60; }
i am using alogcat, an widget on my phone and the thread sleeps about 25 minutes (WTF) :|
Other thing that i verified is that, when phone is charging, the service works OK...
Here is the code:
worker = new Thread(new Runnable()
{
@Override
public void run()
{
Provider[] enabledProviders = feedService.getAllProvidersEnabledData();
// Build a differential list from enabledProviders
DifList<Provider> list = getListForProviders(enabledProviders);
//
// Code starts here
int sleep;
DifNode<Provider> header = list.getFirst();
sleep = header.getInitial();
LinkedList<Provider> data = new LinkedList<Provider>();
Log.d(TAG, String.format("Worker thread started @ %s", now()));
try
{
for(int idx = 0 ; true ; list.reorderFirst(), header = list.getFirst(), idx++)
{
Log.d(TAG, String.format("Iteration %s with sleep %s", idx, sleep));
if(sleep > 0) {
Log.d(TAG, String.format("Next download in %s minutes", sleep));
// Suspend worker thread for sleep time
Thread.sleep(MinutesToMilis(sleep));
Log.d(TAG, "Worker thread waked up from sleep");
}
// Add to data
data.add(header.getKey());
// Set next sleep time
sleep = header.getDifference();
if(sleep != 0)
{
Log.d(TAG, "Worker preparing for update..");
//
// If difference to next is not 0 we dump data to async task
for(Provider p : data){
Log.d(TAG, String.format("Starting update %s @ %s", p.Name, now()));
}
Provider[] arrayData = new Provider[data.size()];
data.toArray(arrayData);
data.clear();
new UpdateBundleOfFeedsTask().execute(arrayData);
}
}
}
catch(InterruptedException ex)
{
Log.d(TAG, String.format("Worker thread was interrupted @ %s", now()));
isRunning = false;
}
Log.d(TAG, String.format("Worker thread exit @ %s", now()));
}
});
回答1:
You should really not be doing it that way, ie having a thread that never dies. I strongly suggest you have a look at alarms : http://developer.android.com/reference/android/app/AlarmManager.html
A good way to go would be :
- set a repeating alarm, maybe one with a different
pendingIntentfor each client, although in your case its seems to be a little too frequent to do that each 5-10 minutes only to read some RSS. - implement a broadcast receiver that listens to the pending intents set by your alarm.
- from the broadcast receiver, start a service that starts a worker thread to read from the network and save to DB.
来源:https://stackoverflow.com/questions/7166333/android-long-service-create-bg-thread-and-i-dont-know-that-is-going-on