问题描述
基本上我开发一个Android的RSS源,我想有一个更新的服务,对于每个源,得到饲料中具体时间。
想象一下:
源1 - 5分钟
源2 - 10分钟
Source3 - 10分钟
我建立差分列表只使用一个线程使对更新的请求。
该数据结构保持这样的:
源1(下一睡眠 - 5),源2(下一睡眠 - 0,来源3(下一睡眠5)..等..
我做的是什么,我总是添加到供应商的名单(包含ID和URL)和睡觉的时候!= 0,我为了更新(使用异步任务,我通过供应商来更新列表和AsyncTask的做的工作对我来说,这是...去上网,分析内容,并更新数据库)
但存在只是睡了集团的利益提供者的包,并发送至AsyncTask的更新一个工作线程。
这是什么问题..
首先,线程不睡觉的具体时间,线程必须睡10分钟,我为转换分钟milis的方法,那就是:
私有静态诠释MinutesToMilis(INT分钟){返回分钟* 1000 * 60; }
我使用alogcat,一个小部件我的手机上,线程睡25分钟左右(WTF):|
这是我验证了另一件事是,当手机正在充电时,服务工程确定...
下面是code:
工人=新主题(新的Runnable()
{
@覆盖
公共无效的run()
{
提供商[] enabledProviders = feedService.getAllProvidersEnabledData(); //建立从enabledProviders差列表
DifList<提供商GT;清单= getListForProviders(enabledProviders); //
// code从这里开始
INT睡眠;
DifNode<提供商GT;标题= list.getFirst(); 睡眠= header.getInitial();
LinkedList的<提供商GT;数据=新的LinkedList<提供商GT;();
Log.d(TAG,的String.format(工人开始线程@%S,现在())); 尝试
{
对于(INT IDX = 0;真实的; list.reorderFirst(),标题= list.getFirst(),IDX ++)
{
Log.d(TAG,的String.format(迭代%s与睡眠%S,IDX,睡觉)); 如果(睡眠大于0){
Log.d(TAG,的String.format(下一步下载在%s分钟,睡觉)); //暂停睡眠时间工作线程
视频下载(MinutesToMilis(睡眠)); Log.d(TAG,工人线程从睡眠中唤醒);
} //添加到数据
data.add(header.getKey()); //设置下一个睡眠时间
睡眠= header.getDifference();
如果(睡眠!= 0)
{
Log.d(TAG,工人preparing进行更新。);
//
//如果差到下一个不为0,我们转储数据异步任务
对于(提供者P:数据){
Log.d(TAG,的String.format(启动更新%S @%S,p.Name,现在()));
} 供应商[] = arrayData新的提供者[data.size()];
data.toArray(arrayData); data.clear();
新UpdateBundleOfFeedsTask()执行(arrayData);
}
}
}
赶上(InterruptedException的前)
{
Log.d(TAG,的String.format(工人线程被中断@%S,现在()));
isRunning = FALSE;
} Log.d(TAG,的String.format(工人线程退出@%S,现在()));
}
});
您应该真的不那样做的方式,即具有永不熄灭的线程。我强烈建议你看看报警:
去一个好方法是:
- 设置重复报警,也许有一个不同的
的PendingIntent
为每一个客户,虽然在你的情况下,其似乎有点过于频繁,在每次5-10分钟仅得读一些RSS。 - 实施监听你的闹钟设置挂起意图的广播接收机。
- ,开始启动一个工作线程从网络读取并保存到数据库的服务。
从广播接收
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 - 5minutesSource2 - 10minutesSource3 - 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()));
}
});
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
pendingIntent
for 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.
这篇关于Android的长期服务创建线程的BG,我不知道是怎么回事的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!