我想要自動保存每當用戶離開應用程序或更改爲其他活動時的主要活動。所以我在活動的OnPause方法中實現了save函數,這很好。問題是保存過程可能需要幾秒鐘,所以我希望在發生進度對話時進行。所以我用這樣的ASyncTask實現了這個功能:AsyncTask仍然阻止UI線程
@Override
public void onPause()
{
super.onPause();
// save sheet when user is leaving activity
SaveTask task = new SaveTask(PlayCharacterActivity.this);
task.execute();
}
private class SaveTask extends AsyncTask <Void, Void, Void> {
private ProgressDialog dialog;
public SaveTask(PlayCharacterActivity activity) {
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(PlayCharacterActivity.this);
dialog.setMessage("Saving...");
dialog.show();
dialog.setIndeterminate(true);
dialog.setCancelable(false);
}
@Override
protected void onPostExecute(Void result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
super.onPostExecute(result);
}
@Override
protected Void doInBackground(Void... params) {
try {
//Log.d("plch:OnPause", "starting save");
Sheet.getInstance().Save();
//Log.d("plch:OnPause", "finished save");
} catch (RuntimeException e) {
e.printStackTrace();
}
return null;
}
}
問題是,直到後臺任務完成後,纔會出現對話框。我可以在logcat中看到主線程仍然被阻塞。我相信它在序列化時在保存函數的中間發生。
保存是這樣的:
public void Save()
{
long dtMili = System.currentTimeMillis();
Date d = new Date(dtMili);
CharSequence s = DateFormat.format("hh:mm:ss", d.getTime());
// use this flag to know whether to back up the saved file or not
boolean saveSuccessful = false;
//_xml = new String("");
dtMili = System.currentTimeMillis();
d = new Date(dtMili);
Log.d("Load/Save", "started serialising: " + DateFormat.format("hh:mm:ss", d.getTime()));
_xml = _instance.Serialise();
dtMili = System.currentTimeMillis();
d = new Date(dtMili);
Log.d("Load/Save", "finished serialising: " + DateFormat.format("hh:mm:ss", d.getTime()));
try
{
//---SD Card Storage---
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/RPGenius");
directory.mkdirs();
File file = new File(directory, _name + ".rpg");
FileOutputStream fOut = new FileOutputStream(file);
Log.d("Saving to: ", file.getAbsolutePath());
//---write the string to the file---
OutputStreamWriter osw = new OutputStreamWriter(fOut);
//DebugHelper.DebugMessage("File contents: " + _xml);
dtMili = System.currentTimeMillis();
d = new Date(dtMili);
Log.d("Load/Save", "started writing file: " + DateFormat.format("hh:mm:ss", d.getTime()));
osw.write(_xml);
osw.flush();
osw.close();
dtMili = System.currentTimeMillis();
d = new Date(dtMili);
Log.d("Load/Save", "finished writing file: " + DateFormat.format("hh:mm:ss", d.getTime()));
saveSuccessful = true;
}
catch (NullPointerException npe)
{
npe.printStackTrace();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
// if the save was completely successfully, back it up
if (saveSuccessful)
{
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/RPGenius");
File file = new File(directory, _name + ".rpg");
if (file.exists())
{
// locate backup directory and create if not present
File backupDirectory = new File (sdCard.getAbsolutePath() + "/RPGenius/Backups");
backupDirectory.mkdirs();
// create target file location/name
File backupFile = new File(backupDirectory, _name + ".rpg");
// attempt to copy file
try {
FileInputStream inStream = new FileInputStream(file);
FileOutputStream outStream = new FileOutputStream(backupFile);
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inStream.close();
outStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
連載是這樣的:
@Override
public String Serialise() {
// produce xml string to represent this object
_indents = 0;
_xml = new String("");
StartXmlItem("Sheet");
//AddSimpleXmlItem("Name", _name);
StartXmlItem("Stats");
for (XmlSerialisable stat: _stats)
{
AddComplexXmlItem(stat);
}
EndXmlItem("Stats");
StartXmlItem("Effects");
for (XmlSerialisable effect: _effects)
{
AddComplexXmlItem(effect);
}
EndXmlItem("Effects");
StartXmlItem("Pages");
for (XmlSerialisable page: _pages)
{
AddComplexXmlItem(page);
}
EndXmlItem("Pages");
EndXmlItem("Sheet");
return _xml;
}
我不是在改進保存/連載方法立刻感興趣,除非它們是相關的progressdialog問題。誰能幫忙?
請將'dialog.show();'移動到'onPreExecute'的最後一行(全部使用對話框後)並再次測試, –
「我可以在logcat中看到主線程仍然被阻塞」 - 我不明白這是如何實現的。你能提供有問題的LogCat條目並解釋你的分析嗎?除此之外,爲什麼你認爲你的表演 - 對話 - 暫停方法能夠正確工作並且首先成爲一個好主意? – CommonsWare