我正在使用 Delphi XE5 和 Firemonkey 玩一个适用于 IOS 和 Android 的应用程序。虽然在 IOS 上应用程序运行良好,但无法在 Android 上启动。原因是在启动阶段它在 System.StartUpCopy.pas 单元中失败。
我有一些与应用程序一起部署的文件(多媒体内容和 XML)。虽然它们在 IOS 上都可以正常复制,但其中一些在 Android 上失败。部署配置是使用 Delphi 中的部署管理器完成的。
- 以下是可以的:assets/internal/profiles/default.xml
- 但是这个失败了:assets/internal/media/images/concert/object4.png
它在运行此代码的第 97 行的“System.StartUpCopy”内失败
ReadCount := AAsset_read(LAssetFile, @Buffer[0], MAX_BUFF_LEN);
但是问题在获得“LAssetFile”的地方有点高
LAssetFile := AAssetManager_open(LAssetManager, M.AsUtf8(OrigFileName).ToPointer, AASSET_MODE_BUFFER);
"AAssetManager_open" 返回nil。为什么我不知道,因为我不知道如何从 API 中获取一些错误代码。整个代码块看起来像这样
function CopyAssetToFile(LAssetManager: PAAssetManager; const AssetFolder, AssetName: string;
const DestinationRoot, DestFolder, FileName: string): Boolean;
var
OrigFileName,
DestFileName,
DestinationPath: string;
ReadCount, WriteCount: Integer;
LAssetFile: PAAsset;
FileHandle: THandle;
Buffer: TBytes;
M: TMarshaller;
begin
Result := True;
if AssetFolder = '' then
OrigFileName := AssetName
else
OrigFileName := IncludeTrailingPathDelimiter(AssetFolder) + AssetName;
if DestFolder <> '' then
begin
DestinationPath := IncludeTrailingPathDelimiter(DestinationRoot) + DestFolder;
DestFileName := IncludeTrailingPathDelimiter(DestinationRoot) + IncludeTrailingPathDelimiter(DestFolder) + FileName;
end
else
begin
DestinationPath := DestinationRoot;
DestFileName := IncludeTrailingPathDelimiter(DestinationRoot) + FileName
end;
if not FileExists(DestFileName) then //do not overwrite files
begin
// Second Create an intermediate buffer.
SetLength(Buffer, MAX_BUFF_LEN);
LAssetFile := nil;
try
if not DirectoryExists(DestinationPath) then
begin
if not ForceDirectories(DestinationPath) then
begin
Exit(False);
end;
end;
// We have a valid AssetManager. Start
LAssetFile := AAssetManager_open(LAssetManager, M.AsUtf8(OrigFileName).ToPointer, AASSET_MODE_BUFFER);
FileHandle := FileCreate(DestFileName);
try
if FileHandle = THandle(-1) then
begin
Exit(False);
end;
repeat
ReadCount := AAsset_read(LAssetFile, @Buffer[0], MAX_BUFF_LEN);
WriteCount := FileWrite(FileHandle, Buffer, 0, ReadCount);
until (ReadCount <= 0) or (ReadCount <> WriteCount);
finally
FileClose(FileHandle);
end;
finally
if (LAssetFile <> nil) then
AAsset_close(LAssetFile);
SetLength(Buffer, 0);
end;
end;
end;
这是原始的 XE5 代码。现在,我在正常文件和失败文件之间看到的唯一区别是目录深度。第一个只有一个级别深度,例如。一个目录,另一个有 3 级深度。我还有一些其他文件也可以复制,并且都只有一级目录深度。
任何人都知道这里可能出了什么问题。我无法进一步调试,因为我已经尽可能深入了。
如果它有助于我在实际设备上进行测试,三星 Galaxy Nexus。
编辑:
发现如果我改变:
资产/内部/媒体/图像/音乐会/object4.png
至
资产/内部/媒体/图像/音乐会/object.png
然后它工作。哇。有什么解释吗?我看了看,数字应该是 android 和资产文件名的有效字符