gpt4 book ai didi

android - Android AsyncTask 中的 ProgressDialog 没有在正确的时间显示

转载 作者:搜寻专家 更新时间:2023-11-01 08:04:01 25 4
gpt4 key购买 nike

所以我在我的 Android 应用程序中进行了这些长时间运行的服务器调用,基本上是 OData。调用的消费者使用 .execute().get() 等待网络线程的响应(我知道正确的方法是使整个过程异步和基于回调,但是没有这些数据,应用程序无法以任何方式运行,完全重新设计它以这种方式运行似乎没有任何好处。

所以我在网上找到了许多 fragment ,其中使用 ProgressDialog 结合 onPreExecute()onPostExecute() 如代码示例所示below 可用于在 AsyncTask 执行时显示进度对话框。我正在使用所提供的示例,但发生的情况是调用开始,它等待网络事务,然后非常快速闪烁并隐藏进度对话框。它可以等待交易整整几秒钟,我知道它正在 doInBackground() 中等待,但对话框直到最后才会弹出,这使得它实际上毫无用处.

在下面的代码中,DoEvents() 位基本上只是一个非常短的 sleep 。我试过使用和不使用它,似乎没有什么区别,但似乎值得一试。

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();
}

我还尝试将 ProgressDialogAsyncTask 中取出,并将其显示在任务“外部”,如下所示。在这种情况下,它甚至不会出现。

ProgressDialog dialog = ProgressDialog.show(ServerAccessLayer.m_context, "", "Loading...", true, false);
String retVal = new GetFromServerTask(ServerAccessLayer.m_context).execute(url).get();
dialog.dismiss();

return retVal;

最佳答案

好的,您的问题是您的 .get().get 是一个阻塞调用。这意味着您不会返回到事件循环(Android 框架中调用 onCreateonPause、事件处理程序、onPostExecute 的代码, onPreExecute 等)直到它返回。如果不返回事件循环,就永远不会进入绘图代码,也不会显示进度对话框。如果你想显示对话框,你需要重新设计你的应用程序来真正异步地使用任务。旁注 - 如果您在 UI 线程上像那样调用 .get() ,您的整个应用程序将卡住并看起来已损坏。这就是为什么他们首先强制人们不要在 UI 线程上进行网络 IO。

关于android - Android AsyncTask 中的 ProgressDialog 没有在正确的时间显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16905526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com