I check fetch.getHasActiveDownloads() to stop the download service. But it sometimes wrongly stops the service even if there is pending downloads. So I dig through the code, I guess you missed this '${Status.ADDED}', '${Status.NONE}' in the below code.
private val pendingCountQuery = "SELECT ${DownloadDatabase.COLUMN_ID} FROM ${DownloadDatabase.TABLE_NAME}" +
" WHERE ${DownloadDatabase.COLUMN_STATUS} = '${Status.QUEUED.value}'" +
" OR ${DownloadDatabase.COLUMN_STATUS} = '${Status.DOWNLOADING}'"
override fun getPendingCount(): Long {
synchronized(lock) {
return try {
val cursor: Cursor? = database.query(pendingCountQuery)
val count = cursor?.count?.toLong() ?: -1L
cursor?.close()
count
} catch (e: Exception) {
-1
}
}
}
May be I am wrong, but issue is there...
So the query will only search for downloads that are pending. Pending meaning downloading or queued for downloading. Downloads with the status of added are not considered active. Its just a record in the database until they are set to queued by calling resume or retry. The database calls are synced so the call will always provide the latest snapshot at the time it is called.
Hmm, seems like db latency. But it is critical. I check for pending downloads when every download complete call back. I guess the millisec difference closes the download service. Below is my logic.
downloadCompleteCallback() -> closeServiceIfNoActiveDownloads();
closeServiceIfNoActiveDownloads(){
if (! fetch.getHasActiveDownloads())
service.stopSelf();
}
Any work around?
Update 1: Why don't you just store a int (pendingCount) in memory if any pending downloads. You auto increase/decrease for download list changes. So we can avoid every time query db & latency. Because we just want to know exactly the pendingCount == 0 or not. We don't need list. So in memory variable might be stable solution.
We can call it like
closeServiceIfNoActiveDownloads(){
if (fetch.getPendingCount() == 0)
service.stopSelf();
}
So it is real time!
Update 2:
Alrighty, I think I solved the puzzle myself, got worked using an Atomic Integer.
// AtomicInteger is for thread safe
private static AtomicInteger pendingDownloads = new AtomicInteger(0);
new FetchListener() {
@Override
public void onAdded(@NotNull Download download) {
pendingDownloads.incrementAndGet();
}
@Override
public void onCompleted(@NotNull Download download) {
pendingDownloads.decrementAndGet();
closeServiceIfNoActiveDownloads();
}
@Override
public void onError(@NotNull Download download, @NotNull Error error, @org.jetbrains.annotations.Nullable Throwable throwable) {
pendingDownloads.decrementAndGet();
closeServiceIfNoActiveDownloads();
}
@Override
public void onPaused(@NotNull Download download) {
pendingDownloads.decrementAndGet();
closeServiceIfNoActiveDownloads();
}
@Override
public void onResumed(@NotNull Download download) {
pendingDownloads.incrementAndGet();
}
@Override
public void onCancelled(@NotNull Download download) {
pendingDownloads.decrementAndGet();
closeServiceIfNoActiveDownloads();
}
};
private synchronized void closeServiceIfNoActiveDownloads() {
if (pendingDownloads.intValue() <= 0)
stopSelf();
}
No more slow db query, no more waiting, fast, simple & neat, more importantly, it works!
If you can add it to the library, it will be handy!
@jpvs0101 I will try to have a look over the weekend.
Still looking into this. Have been very busy lately. Hoping to get some time soon.
I have the same issue
@jpvs0101 @munix Fetch v3.0.1 has been released with a new method hasActiveDownloads(includeAddedDownloads: Boolean, func: FuncFetch.hasActiveDownloads has not been deprecated yet until I get feedback.
@jpvs0101 Thanks for your proposed solutions but they would not work well inside the Fetch library especially with version 3 now allowing users of the library to create their own fetch database managers.
@jpvs0101 @munix Fetch v3.0.1 has been released with a new method hasActiveDownloads(includeAddedDownloads: Boolean, func: Func). Please test and let me know how it works for you.
Fetch.hasActiveDownloadshas not been deprecated yet until I get feedback.@jpvs0101 Thanks for your proposed solutions but they would not work well inside the Fetch library especially with version 3 now allowing users of the library to create their own fetch database managers.
Seems like hasActiveDownloads(includeAddedDownloads: Boolean, func: Func) works. Actually it checks for both Added & Queued downloads. I found it by digging the source code. I think you should clearly mention this in the documentation.
Also I love you added new fields on the Download objects. Fields: etaInMilliSeconds, downloadedBytesPerSecond. Phew... relief of complex wiring implementation recycler adapter!
Thanks for these simplification.
@jpvs0101 sounds good! Thanks for your feedback. I will def clean and update the documentation. Will remove the old Fetch.hasActiveDownloads method in the next release.
@jpvs0101 Shameless plug but I do value your feedback. Please check out my other library Dispatcher and let me know what you think.
@jpvs0101 Shameless plug but I do value your feedback. Please check out my other library Dispatcher and let me know what you think.
@tonyofrancis Sorry, I have no interest/need on that lib, so i can't give you useful feedback!
But all the best for the new library. Thanks!
Most helpful comment
@jpvs0101 I will try to have a look over the weekend.