所以我有這些長期運行的服務器調用,基本上是在我的Android應用程序中進行的OData。這些調用的使用者使用.execute().get()
來等待來自網絡線程的響應(我知道正確的方法是使整個事物成爲異步和基於回調的,但是沒有這些數據,應用程序將無法以任何方式運行,並且完全重新構建它以這種方式工作似乎沒有提供任何好處)。Android中的ProgressDialog AsyncTask沒有在正確的時間顯示
所以我發現很多片段在網上,其中聯合使用ProgressDialog
與onPreExecute()
和onPostExecute()
如下面的代碼示例中可用來顯示,而AsyncTask
執行進度對話框。我正在使用提供的樣本,但會發生什麼情況是電話開始,它等待網絡交易,然後很快閃爍並隱藏進度對話框。它可以等待整個交易,並且我知道它正在等待doInBackground()
,但對話框只是在最後才彈出,使其無效。
在下面的代碼DoEvents()
位基本上只是一個非常短暫的睡眠。我試過,沒有它,似乎沒有區別,但它似乎值得嘗試。
class GetFromServerTask extends AsyncTask<String, Void, String>
{
private Context context;
private ProgressDialog dialog;
public GetFromServerTask(Context ctx) {
context = ctx;
dialog = new ProgressDialog(ctx);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog.setMessage("Loading...");
dialog.show();
DoEvents();
}
@Override
protected String doInBackground(String... parms) {
if(InOfflineMode)
return "notdeserializable";
String url = parms[0];
HttpURLConnection urlConnection = null;
try {
URL typedUrl = new URL(url);
urlConnection = (HttpURLConnection) typedUrl.openConnection();
//Add Authorization token
if(InDebugMode) {
urlConnection.addRequestProperty("AuthToken", AuthToken);
} else {
urlConnection.addRequestProperty("Authorization", "Bearer " + AuthToken);
}
urlConnection.addRequestProperty("Accept", "application/json");
DoEvents();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
byte[] contents = new byte[in.available()];
int bytesRead = 0;
String strContents = "";
while((bytesRead = in.read(contents)) != -1){
strContents += new String(contents, 0, bytesRead);
DoEvents();
}
if(strContents.startsWith("<HTML>"))
return "Error: Received unexpected HTML when connecting to service. Make sure you are not connected to a WIFI that requires authentication.";
return strContents;
} catch(UnknownHostException hex) {
return "Error: Could not find server address. Make sure you are connected to the internet. If you just changed connections (ie: turning WIFI on or off) it make take a minute to refresh";
}
catch(Exception ex) {
String msg = "Error: " + ex.getClass().getName() + ": " + ex.getMessage();
Log.e("TE", msg);
return msg;
} finally {
if(urlConnection != null)
urlConnection.disconnect();
}
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(dialog != null && dialog.isShowing())
dialog.dismiss();
DoEvents();
}
}
我也試過在SO(如下圖所示),建議其他地方略有不同版本完全相同的結果:
protected void onPreExecute() {
dialog=ProgressDialog.show(context, "", "Loading...", true, false);
super.onPreExecute();
}
我也試着服用ProgressDialog
出AsyncTask
所有的一起並將其顯示在「任務外」,如下所示。在這種情況下,它甚至不會出現。
ProgressDialog dialog = ProgressDialog.show(ServerAccessLayer.m_context, "", "Loading...", true, false);
String retVal = new GetFromServerTask(ServerAccessLayer.m_context).execute(url).get();
dialog.dismiss();
return retVal;
如果您按照此處所述的修復方法進行操作,會發生什麼情況? (http://stackoverflow.com/questions/11943133/android-asynctask-onpreexecute-not-called-indeterminantly) –
@肯狼:相同的行爲。在進度對話框快速彈出然後消失之前,可以看到UI響應(即:從服務器拉取數據的微調器加載)。 – Gakidou
由於執行任務立即返回,您將修補程序顯示爲不在任務之外。這意味着它會立即要求解僱。要做到這一點,你可以在執行前調用show,並在onPostExecute中調用dismiss。 –