我目前创建了一个使用XmlSerializer从对象创建XML文件的函数。我一直在研究使用不同形式的多线程,以便在GUI仍然可用且仍在更新的同时将文件保存在后台。我看过使用AsyncTask来做这件事,但我不确定实现它的最佳方法是什么。请任何人帮助我,并提前感谢你。
这是我到目前为止的代码:
private String fileName;
private DataObjects dataObjects;
public SetCachedValuesFile()
{
}
public void setFileName(String refFileName)
{
fileName = refFileName;
}
public void setDataObjects(DataObjects refDataObjects)
{
dataObjects = refDataObjects;
}
public String getFileName()
{
return fileName;
}
public DataObjects getDataObjects()
{
return dataObjects;
}
public void updateValues()
{
ArrayList<DataObject> arrayListDataObject = dataObjects.getDataObjects();
try
{
/* Creates a new file and its directory. */
File directory = new File(Environment.getExternalStorageDirectory() + "/XML_FILES/");
directory.mkdirs();
File newFile = new File(directory, fileName + ".xml");
FileOutputStream fos = new FileOutputStream(newFile);
/* Creates a new XML serializer which creates the structure of the XML file. */
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(fos, "UTF-8");
serializer.startDocument(null, true);
serializer.startTag("", "CachedValues");
for(DataObject dataObject : arrayListDataObject)
{
if(dataObject.getClass().equals(StringDataObject.class))
{
StringDataObject stringDataObject = (StringDataObject) dataObject;
String address = HexFunctions.toString(stringDataObject.getAddress());
String value = stringDataObject.getValue();
serializer.startTag("", "DataObject");
serializer.startTag("", "Address");
serializer.text(address);
serializer.endTag("", "Address");
serializer.startTag("", "Value");
serializer.text(value);
serializer.endTag("", "Value");
serializer.endTag("", "DataObject");
System.out.println("String data object added to file.");
}
else if(dataObject.getClass().equals(IntDataObject.class))
{
IntDataObject intDataObject = (IntDataObject) dataObject;
String address = HexFunctions.toString(intDataObject.getAddress());
String value = Integer.toString(intDataObject.getValue());
serializer.startTag("", "DataObject");
serializer.startTag("", "Address");
serializer.text(address);
serializer.endTag("", "Address");
serializer.startTag("", "Value");
serializer.text(value);
serializer.endTag("", "Value");
serializer.endTag("", "DataObject");
System.out.println("Int data object added to file.");
}
else if(dataObject.getClass().equals(FloatDataObject.class))
{
FloatDataObject floatDataObject = (FloatDataObject) dataObject;
String address = HexFunctions.toString(floatDataObject.getAddress());
String value = Float.toString(floatDataObject.getValue());
serializer.startTag("", "DataObject");
serializer.startTag("", "Address");
serializer.text(address);
serializer.endTag("", "Address");
serializer.startTag("", "Value");
serializer.text(value);
serializer.endTag("", "Value");
serializer.endTag("", "DataObject");
System.out.println("Float data object added to file.");
}
else if(dataObject.getClass().equals(DoubleDataObject.class))
{
DoubleDataObject doubleDataObject = (DoubleDataObject) dataObject;
String address = HexFunctions.toString(doubleDataObject.getAddress());
String value = Double.toString(doubleDataObject.getValue());
serializer.startTag("", "DataObject");
serializer.startTag("", "Address");
serializer.text(address);
serializer.endTag("", "Address");
serializer.startTag("", "Value");
serializer.text(value);
serializer.endTag("", "Value");
serializer.endTag("", "DataObject");
System.out.println("Double data object added to file.");
}
}
serializer.endTag("", "CachedValues");
serializer.endDocument();
serializer.flush();
fos.close();
System.out.println("File created");
System.out.println("File name: " + newFile.getAbsolutePath());
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
答案 0 :(得分:11)
AsyncTask类实现了一种最佳实践模式,用于将耗时(但短暂的)处理移动到后台线程并同步回UI线程,以便在完成时将更新应用于UI。请注意,此类任务不会在重新启动活动时保留,因此,例如,如果设备的方向发生更改,则会取消这些任务。
但是,如果您不需要将UI更新为后台任务的一部分(这里似乎就是这种情况),那么只需使用通常更简单的Thread类(编辑:添加的代码)从后台线程更新UI):
Handler handler = new Handler(); //Optional. Define as a variable in your activity.
Runnable r = new Runnable()
{
@Override
public void run()
{
// your code here
handler.post(new Runnable() //If you want to update the UI, queue the code on the UI thread
{
public void run()
{
//Code to update the UI
}
});
}
};
Thread t = new Thread(r);
t.start();
请注意,这种类型的线程会在重新启动活动时保持不变,因此通常应该运行完成。
要将此作为AsyncTask(如果需要更新UI,这可能是更好的选择),可以通过以下方式实现:
在您的活动中,创建Async类的实例并执行。
SaveData save = new SaveData();
save.execute();
将AsyncTask子类作为活动中的私有类
private class SaveData extends AsyncTask<String, Void, Boolean>{
@Override
protected Boolean doInBackground(String... params) {
// your background code here. Don't touch any UI components
if(your code worked...)
return true;
else
return false;
}
protected void onPostExecute(Boolean result) {
//This is run on the UI thread so you can do as you wish here
if(result)
Toast successful
else
Toast unsuccessful
}
}
答案 1 :(得分:1)
要添加到NigelK的答案有一点是,如果您使用AsyncTask,则只能使用一次。所以你不能按如下方式调用它两次:
SaveData save = new SaveData();
save.execute();
//Later
save.execute();
相反,您需要执行以下操作:
SaveData save1 = new SaveData();
save1.execute();
//Later
SaveData save2 = new SaveData();
save2.execute();
此外,如果您需要重复运行任务,您可能需要使用处理程序并在runnable中调用它,如下所示:
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
SaveData save = new SaveData();
save.execute();
}
};
handler.postDelayed(runnable, 500);
请参阅这些链接。 AsyncTask Threading Rule - Can it really only be used once? Call asynctask in handler