使用Intent.ACTION_GET_CONTENT的意图来选择XML文件。在onActivityResult()中,我启动了一个asynctask来将这个XML文件读入数据库。
我希望asynctask显示一个进度条,以确保在应用程序进行之前由于错误处理和预期的UI更改而完成。
只要执行了asynctask,就会显示intent创建的选择器对话框 - 即应用程序仍在onActivityResult()块中,并且没有显示progressdialog。 onPostExecute()被称为AFTER onActivityResult()结束。
我也尝试过使用.get()make asynctask在应用程序进行之前完成,但没有运气......
我认为这归结为错误的逻辑......
除了importDB是它自己的一个类之外,一切都在一个活动中发生。
意图就是这样开始......
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("text/xml");
startActivityForResult(Intent.createChooser(intent, "Select XML"), RC_IMPORT_FILE);
...而onActivityResult()看起来像这样......
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (resultCode) {
case Activity.RESULT_OK:
switch (requestCode) {
case RC_IMPORT_FILE:
Uri uri = data.getData();
if (data != null) {
importDB(new File(uri.toString()), uri, false);
};
break;
... more switch statements...
}
}
...而且importDB看起来像这样......
private void importDB(File file, Uri uri, boolean xmlRaw, Context context) {
int error = 0;
ImportDataBase importDataBase = new ImportDataBase();
importDataBase.setContext(this);
importDataBase.setUri(uri);
importDataBase.xmlRaw(xmlRaw);
try {
importDataBase.execute("ImportDB").get();
} catch (ExecutionException ee) {
logException(TAG, "importDB", ee);
error = 1;
} catch (InterruptedException ie) {
logException(TAG, "importDB", ie);
error = 2;
}
}
...而async任务(ImportDataBase)看起来像这样......
import android.app.ProgressDialog;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.widget.Toast;
import java.io.InputStream;
public class ImportDataBase extends AsyncTask<String, Integer, String> {
private static final String TAG = "ImportDataBase";
private Context context;
private ProgressDialog progressDialog;
private Uri uri = null;
private InputStream xmlStream = null;
private XMLParser xmlParser;
private boolean xmlRaw = true;
private int errorCode = 0;
public void xmlRaw(boolean xmlRaw) {
this.xmlRaw = xmlRaw;
}
public void setUri(Uri uri) { this.uri = uri; }
public void setInputStream(InputStream inputStream) { this.xmlStream = inputStream; }
public void setContext(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = this.context;
progressDialog.setCancelable(false);
progressDialog.setMessage("Please wait...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
xmlParser = new XMLParser();
xmlParser.xmlRaw(xmlRaw);
}
@Override
protected String doInBackground(String... params) {
String result = "0";
int error = 0;
InputStream inputStream = null;
try {
if (uri != null) inputStream = context.getContentResolver().openInputStream(uri);
else inputStream = this.xmlStream;
} catch (Exception e) {
result = "1000";
}
if (error == 0) {
try {
xmlParser.readXML(inputStream);
} catch (NullPointerException npe) {
result ="10";
} catch (Exception e) {
result ="10";
}
} else result = "31";
switch (xmlParser.getError()) {
case 1 : result = "10"; break; // XML Parser error
case 2 : result = "15"; break; // URLERROR;
case 3 : result = "30"; break; // IOFileError
case 4 : result = "31"; break; // FileError;
case 5 : result = "32"; break; // FileDoesNotExists;
default : result = "0";
}
try {
inputStream.close();
} catch (Exception e) {
}
return result;
}
@Override
protected void onPostExecute(String string) {
super.onPostExecute(string);
String error = "";
if (Integer.valueOf(string) > 0) {
switch (Integer.valueOf(string)) {
case 1:
error = "You need to update the app to the newest version!";
errorCode =1;
break;
case 10 :
error = "XML parser error! Wrong file?";
errorCode =10;
break;
case 15 :
error = "Wrong URL!";
errorCode =15;
break;
case 30 :
error = "File read/Write error!";
errorCode =30;
break;
case 31 :
error = "File error";
errorCode =31;
break;
case 32 :
error = "File does not exsits!";
errorCode =32;
break;
case 99 :
error = "Unknwon XML parser error!";
errorCode =99;
break;
case 100:
error = "Database error! Retry or reinstall app!";
errorCode =100;
break;
case 1000:
error = "Unknown error!";
errorCode =1000;
break;
default:
error = "Unknwon error!";
}
Toast.makeText(context, error, Toast.LENGTH_SHORT).show();
}
if ( progressDialog.isShowing() ) progressDialog.dismiss();
}
public int getError() {
return this.errorCode;
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}
有关如何让应用程序等待asynctask完成的任何建议?在调用importDB()并希望显示进度条之前,是否可以在onActivityResult()内关闭对话框窗口?
答案 0 :(得分:0)
基本上你应该从不阻止任何事情。我会使用AsyncTask在启动时显示ProgressDialog并在完成时隐藏它:
private ProgressDialog progressDialog;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// blahblah
if (data != null) {
new ImportTask(new File(uri.toString()), uri).execute();
}
// blahblah
}
class ImportTask extends AsyncTask<Void, Void, Void> {
private File file;
private Uri uri;
ImportTask( File file, Uri uri ){
this.file = file;
this.uri = uri;
}
@Override
protected void onPreExecute() {
progressDialog.show();
}
@Override
protected Void doInBackground( Void... voids ) {
importDB(file, uri, false);
return null;
}
@Override
protected void onPostExecute( Void res ) {
progressDialog.hide();
}
}
通过这种方式,您可以决定在importDB()
正在运行期间并行执行其他操作。