我正在使用IntentService从列表中下载200个大型JPG。在加载时,用户可以跳过未加载的JPG并加载JPG #156,但在加载之后,应该继续加载其余部分。它就像一个懒惰的装载器..。但当它空闲时,它会继续。
我之前使用了onHandleIntent,并从#1到#200...当我尝试为JPG #156发送另一个IntentService调用时,这显然不起作用。因此,对#156的调用只有在onHandleIntent完成#200之后才会发生。
然后我对其进行了更改,以便onHandleIntent将请求#156重新排序为列表的顶部,然后请求列表的顶部(并下载JPG),然后将其从列表中删除。然后,它再次调用IntentService,从递归/堆栈溢出的方式来看,这听起来相当危险。它有时会起作用,我可以看到文件#156被放在第一位...有时候。
有没有更好的方法来做这件事?我能想到的一种方法是通过一个数据库来运行它。
编辑:这是我想出来的:
code
public class PBQDownloader extends IntentService {
int currentWeight = 0;
PriorityBlockingQueue<WeightedAsset> pbQueue = new PriorityBlockingQueue<WeightedAsset>(100, new CompareWeightedAsset());
public PBQDownloader() {
super("PBQDownloader");
}
public PBQDownloader(String name) {
super(name);
}
@Override
protected void onHandleIntent(Intent intent) {
String downloadUrl = "-NULL-";
Bundle extras = intent.getExtras();
if (extras!=null) {
downloadUrl = extras.getString("url");
Log.d("onHandleIntent 1.1", "asked to download: " + downloadUrl);
} else {
Log.d("onHandleIntent 1.2", "no URL sent so let's start queueing everything");
int MAX = 10;
for (int i = 1; i <= MAX; i++) {
// should read URLs from list
WeightedAsset waToAdd = new WeightedAsset("url: " + i, MAX - i);
if (pbQueue.contains(waToAdd)) {
Log.d("onStartCommand 1", downloadUrl + " already exists, so we are removing it and adding it back with a new priority");
pbQueue.remove(waToAdd);
}
pbQueue.put(waToAdd);
}
currentWeight = MAX + 1;
}
while (!pbQueue.isEmpty()) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
WeightedAsset waToProcess = pbQueue.poll();
Log.d("onHandleIntent 2 DOWNLOADED", waToProcess.url);
}
Log.d("onHandleIntent 99", "finished all IntentService calls");
}
@Override
public int onStartCommand(Intent intent, int a, int b) {
super.onStartCommand(intent, a, b);
currentWeight++;
String downloadUrl = "-NULL-";
Bundle extras = intent.getExtras();
if (extras!=null) downloadUrl = extras.getString("url");
Log.d("onStartCommand 0", "download: " + downloadUrl + " with current weight: " + currentWeight);
WeightedAsset waToAdd = new WeightedAsset(downloadUrl, currentWeight);
if (pbQueue.contains(waToAdd)) {
Log.d("onStartCommand 1", downloadUrl + " already exists, so we are removing it and adding it back with a new priority");
pbQueue.remove(waToAdd);
}
pbQueue.put(waToAdd);
return 0;
}
private class CompareWeightedAsset implements Comparator<WeightedAsset> {
@Override
public int compare(WeightedAsset a, WeightedAsset b) {
if (a.weight < b.weight) return 1;
if (a.weight > b.weight) return -1;
return 0;
}
}
private class WeightedAsset {
String url;
int weight;
public WeightedAsset(String u, int w) {
url = u;
weight = w;
}
}
}code
然后我有这个活动:
code
public class HelloPBQ extends Activity {
int sCount = 10;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button tv01 = (Button) findViewById(R.id.tv01);
Button tv02 = (Button) findViewById(R.id.tv02);
Button tv03 = (Button) findViewById(R.id.tv03);
tv01.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
doPBQ();
}
});
tv02.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
doInitPBQ();
}
});
tv03.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sCount = 0;
}
});
}
private void doInitPBQ() {
Intent intent = new Intent(getApplicationContext(), PBQDownloader.class);
//intent.putExtra("url", "url: " + sCount);
startService(intent);
}
private void doPBQ() {
sCount++;
Intent intent = new Intent(getApplicationContext(), PBQDownloader.class);
intent.putExtra("url", "url: " + sCount);
startService(intent);
}
}code
现在麻烦的是,我必须保持一个不断增加的计数器,它冒着超出整数界限(WeightedAsset.weight)的风险--有没有一种方法可以通过编程添加到队列中,并让它自动成为队列的头部?我尝试用字符串替换WeightedAsset,但它没有像我想要的那样作为先进先出而不是后进先出栈。
发布于 2011-04-25 02:12:24
下面是我第一次尝试的方法:
步骤1:让IntentService保持在PriorityBlockingQueue上。
Step #2:让onHandleIntent()遍历PriorityBlockingQueue,在每个文件从队列中弹出时依次下载。
步骤#3:让onStartCommand()查看命令是否为"kick off all downloads“命令(在这种情况下,链接到超类)。如果是“按优先顺序下载”命令,则在PriorityBlockingQueue中重新排列该条目的优先顺序,以便onHandleIntent()在当前下载完成时接下来的条目。
https://stackoverflow.com/questions/5771100
复制相似问题