そのため、Android アプリケーションで基本的に OData が行われていることに対して、これらの長時間実行されるサーバー呼び出しがあります。呼び出しのコンシューマーは.execute().get()
、ネットワーク スレッドからの応答を待機するために使用します (適切な方法は、すべてを非同期でコールバック ベースにすることですが、アプリはこのデータがなければ機能しません。そのように働くことは何の利益ももたらさないようです)。
そのため、以下のコード サンプルに示すようにと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;