问题描述
我一直在使用 RAD Studio 10.4 开发移动应用程序。我想在“Run”开始时创建并显示餐厅的菜单。我正在 FormCreate() 中尝试在另一个线程中执行以下操作:
我不想让用户等待很长时间,所以我想在另一个线程中执行这些任务,以便先显示菜单,然后在下载食物图像时将它们添加到菜单上。我几乎做到了,除了我经常看到一些带有空白或白线的图像。
代码如下:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
_di_ITask task = TTask::Create([&](){
showMenu();
});
task->Start();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::showMenu()
{
try
{
String content = fetchMenu();
loadXML(content);
}
catch(...)
{
//ShowMessage("Something wrong is happening...");
}
vecImgStream = loadImages();
addImgToList(vecImgStream,vectItemOfListView,m_ListView);
attachItemClickListener();
isIndicatorVisible(false);
//delete the vector of pointers
for(TMemoryStream* pMStream : vecImgStream)
{
delete pMStream;
}
vecImgStream.clear();
}
//---------------------------------------------------------------------------
String __fastcall TForm1::fetchMenu()
{
String content;
try
{
AnsiString url = "https://www.test.com/API/MenuGET.PHP";
RESTClient1->BaseURL = url;
RESTRequest1->AddParameter("BannerID","24");
RESTRequest1->AddParameter("SuccursaleID","1");
RESTRequest1->AddParameter("Password","password");
RESTRequest1->Method = TRESTRequestMethod(rmGET);
//GET
RESTRequest1->Execute();
//Retrieve the content
content = RESTResponse1->Content;
}
catch(std::exception&)
{
content = "An error occured!";
}
return content;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::loadXML(String content)
{
//creat main list with category name
_di_IXMLDocument menuXML = strToXML(content);
createMainList(menuXML);
}
//---------------------------------------------------------------------------
_di_IXMLDocument __fastcall TForm1::strToXML(String content)
{
//XML
XMLDocument1->Active = true;
_di_IXMLDocument xml = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
//Convert: String -> XML
xml->LoadFromXML(content);
return xml;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::createMainList(_di_IXMLDocument menuXML)
{
//Clear up the list
m_ListView->Items->Clear();
m_ListView->BeginUpdate();
//Position myself at <Menu>
Menu = menuXML->DocumentElement;
//Position myself at <Categories>
_di_IXMLNode Categories = Menu->ChildNodes->FindNode("Categories");
for (int categ = 0; categ < Categories->ChildNodes->Count; categ++)
{
//Position myself at each <Item>
_di_IXMLNode item = Categories->ChildNodes->GetNode(categ);
//Retrieve and show <NameFR>'s value under <Item>
AnsiString nameFR = item->ChildNodes->Nodes[WideString("NameFR")]->Text;
//Retrieve <Image>'s value (photo's path) under each <Item>
AnsiString imagePath = item->ChildNodes->Nodes[WideString("Image")]->Text;
//Bind the name and the photo's path of each item
//menuImage[nameFR] = imagePath;
int categNumber = (item->ChildNodes->GetNode("ID")->Text).ToInt();
mapCategory[nameFR] = categNumber;
TListViewItem* itemOfListView = m_ListView->Items->Add();
//Add the item's name to each row of the list
itemOfListView->Text = nameFR;
//*** Prep to download images later ***
vectItemOfListView.push_back(itemOfListView);
if(!imagePath.IsEmpty())
{
vectorPhotoPath.push_back(imagePath);
}
else
{
vectorPhotoPath.push_back("");
}
}
m_ListView->EndUpdate();
m_ListView->Enabled = true;
}
//---------------------------------------------------------------------------
std::vector<TMemoryStream*> __fastcall TForm1::loadImages()
{
/*************************
For the first time use:
1.Download images
2.Save them in cache
3.Add and show them onto the list
From the second time use:
1.Load images
2.Add and show them onto the list
**************************/
std::vector<TMemoryStream*> vecImgStream;
vecImgStream = loadImageFromFile();
if(vecImgStream.empty())
{
vecImgStream = getimagestreams();
saveImagetoFile(vecImgStream);
}
else
{
//ShowMessage("Images found");
}
return vecImgStream;
}
//---------------------------------------------------------------------------
std::vector<TMemoryStream*> __fastcall TForm1::loadImageFromFile()
{
std::vector<TMemoryStream*> vectPhotoStream;
int counter = 0;
UnicodeString fileName;
do{
//fileName = file path + Integer value(between 0 and 33) +".jpeg"
//Ex. u"/data/user/0/com.embarcadero.Project1/files/0.jpeg"
fileName =
System::IoUtils::TPath::Combine(System::IoUtils::TPath::GetDocumentsPath(),IntToStr(counter) + ".jpeg");
if(FileExists(fileName))
{
//text = "Image found";
vectPhotoStream.push_back(new TMemoryStream);
vectPhotoStream[counter]->LoadFromFile(fileName);
}
counter++;
}
while(FileExists(fileName));
return vectPhotoStream;
}
std::vector<TMemoryStream*> TForm1::getimagestreams()
{
std::vector<TMemoryStream*> vecImgStream;
vecImgStream = downloadImage(vectorPhotoPath);
return vecImgStream;
}
//---------------------------------------------------------------------------
std::vector<TMemoryStream*> __fastcall TForm1::downloadImage(std::vector<String> &vectorPhotoPath)
{
std::vector<TMemoryStream*> vecImgStream;
for(int i=0; i<vectorPhotoPath.size(); i++)
{
String imagePath = vectorPhotoPath[i];
if(!imagePath.IsEmpty())
{
//1. download an image and keep it as a stream
TMemoryStream* pStream = loadDefaultimage(imagePath);
//2. Put it into the vector
vecImgStream.push_back(pStream);
}
else
{
//Need to put something empty in the vector.
static char Buffer[2048];
memset(Buffer,2048);
sprintf(Buffer,"%s","");
int Len = strlen(Buffer);
TMemoryStream *pMyStream = new TMemoryStream();
pMyStream->Write(Buffer,Len);
//Put it into the vector
vecImgStream.push_back(pMyStream);
}
}
return vecImgStream;
}
//---------------------------------------------------------------------------
TMemoryStream* __fastcall TForm1::loadDefaultimage(String imagePath)
{
UnicodeString URLphoto = "http://www.test.com/" + imagePath;
TMemoryStream* photoStream;
THTTPClient* HTTPclient;
try {
photoStream = new TMemoryStream();
photoStream->Position = 0;
HTTPclient = THTTPClient::Create();
//GET request
HTTPclient->Get(URLphoto,photoStream);
}
catch (Exception & e)
{
ShowMessage (e.Message);
}
delete HTTPclient;
return photoStream;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::addImgToList(
std::vector<TMemoryStream*> &vecImgStream,std::vector<TListViewItem*> &vectItemOfListView,TListView* m_ListView
){
m_ListView->BeginUpdate();
for(int i=0; i < vecImgStream.size(); i++)
{
if(!vecImgStream[i]->Size == 0)
{
TMemoryStream* pStream = vecImgStream[i];
//put the photo onto the list
vectItemOfListView[i]->Bitmap->LoadFromStream(pStream);
}
}
m_ListView->EndUpdate();
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)