您的位置:首页 > 大数据 > 人工智能

CTS DownloadManagerTest testMinimumDownload failed

2016-04-27 17:56 411 查看
DownloadManagerTest testMinimumDownload代码如下:

public void testMinimumDownload() throws Exception {
final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
try {
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
mContext.registerReceiver(receiver, intentFilter);

long id = mDownloadManager.enqueue(new Request(getMinimumDownloadUrl()));
receiver.waitForDownloadComplete(LONG_TIMEOUT, id);

ParcelFileDescriptor fileDescriptor = mDownloadManager.openDownloadedFile(id);
assertEquals(MINIMUM_DOWNLOAD_BYTES, fileDescriptor.getStatSize());

Cursor cursor = null;
try {
cursor = mDownloadManager.query(new Query().setFilterById(id));
assertTrue(cursor.moveToNext());
assertEquals(DownloadManager.STATUS_SUCCESSFUL, cursor.getInt(
cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)));
assertEquals(MINIMUM_DOWNLOAD_BYTES, cursor.getInt(
cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)));
assertFalse(cursor.moveToNext());
} finally {
if (cursor != null) {
cursor.close();
}
}

assertRemoveDownload(id, 0);
} finally {
mContext.unregisterReceiver(receiver);
}
}
函数一开始调用DownloadManager的openDownloadFile:

public ParcelFileDescriptor openDownloadedFile(long id) throws FileNotFoundException {
return mResolver.openFileDescriptor(getDownloadUri(id), "r");
}
最终调用的是DownloadProvider的openFile:

@Override
public ParcelFileDescriptor openFile(final Uri uri, String mode) throws FileNotFoundException {
......
} else {
try {
// When finished writing, update size and timestamp
return ParcelFileDescriptor.open(file, pfdMode, mHandler, new OnCloseListener() {
@Override
public void onClose(IOException e) {
final ContentValues values = new ContentValues();
values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, file.length());
values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION,
System.currentTimeMillis());
update(uri, values, null, null);

if (shouldScan) {
final Intent intent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
getContext().sendBroadcast(intent);
}
}
});
} catch (IOException e) {
throw new FileNotFoundException("Failed to open for writing: " + e);
}
}
......
}
这个方法返回ParcelFileDescriptor对象同时为其设置了一个OnCloseListener。

当下载完成之后会关闭这个ParcelFileDescriptor会调用这个OnCloseListener。然后后者会将ParcelFileDescriptor对应的文件大小信息更新到数据库中。

testMinimumDownload接着回去调用DownloadManager的enqueue,最终会导致DownloadProvider启动一个DownloadThread去下载对应的文件。

public class DownloadThread implements Runnable {

......

@Override
public void run() {

......

try {

......

executeDownload();

......

} catch(...) {

......

} finally {

logDebug("Finished with status " + Downloads.Impl.statusToString(mInfoDelta.mStatus));

mNotifier.notifyDownloadSpeed(mId, 0);

finalizeDestination();

mInfoDelta.writeToDatabase();

if (Downloads.Impl.isStatusCompleted(mInfoDelta.mStatus)) {
mInfo.sendIntentIfRequested();
}

TrafficStats.clearThreadStatsTag();
TrafficStats.clearThreadStatsUid();

netPolicy.unregisterListener(mPolicyListener);

if (wakeLock != null) {
wakeLock.release();
wakeLock = null;
}

}

.....

}

......

}

这里下载完成后会通知DownloadProvider下载完成,进而导致前面的ParcelFileDescriptor对象被close导致OnCloseListener执行。

同时DownloadThread继续执行finalizeDestination方法:

private void finalizeDestination() {

......

if (Downloads.Impl.isStatusError(mInfoDelta.mStatus)) {

......

} else if (Downloads.Impl.isStatusSuccess(mInfoDelta.mStatus)) {

// When success, open access if local file
if (mInfoDelta.mFileName != null) {
try {
// TODO: remove this once PackageInstaller works with content://
Os.chmod(mInfoDelta.mFileName, 0644);
} catch (ErrnoException ignored) {
}

if (mInfo.mDestination != Downloads.Impl.DESTINATION_FILE_URI) {
try {
// Move into final resting place, if needed
final File before = new File(mInfoDelta.mFileName);
final File beforeDir = Helpers.getRunningDestinationDirectory(
mContext, mInfo.mDestination);
final File afterDir = Helpers.getSuccessDestinationDirectory(
mContext, mInfo.mDestination);
if (!beforeDir.equals(afterDir)
&& before.getParentFile().equals(beforeDir)) {
final File after = new File(afterDir, before.getName());
if (before.renameTo(after)) {
mInfoDelta.mFileName = after.getAbsolutePath();
}
}
} catch (IOException ignored) {
}
}
}

}

......

}

这里会重命名下载的文件。如果这个操作比OnCloseListener先被执行就导致,onCloseListener将数据库的下载文件大小信息跟新为0.

从而导致testMinimumDownload后续查询下载文件大小做assert操作失败。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android