我有一个主要的Activity,我的片段的额外类,在这个片段里面是一个AsyncTask,它收集来自各种android库(Wifi SSID,BSSID等)的数据。当我启动我的应用程序时,该应用程序显示一个空白屏幕,没有任何UI。然后在大约2秒后,显示整个数据。我实际上想在背景中将我的TextView显示为“未连接到wifi网络”,同时显示ProgressDialog直到显示数据。我在MainActivity中有ProgressDialog,并在我的AsyncTask onProgressUpdate中调用它
MainActivity.progressDialog = ProgressDialog.show(MainActivity.c,
"ProgressDialog Title",
"ProgressDialog Body");
我在doInBackground方法中更新我的TextViews(通过片段外的另一个方法)
((Activity) getActivity()).runOnUiThread(new Runnable() {
答案 0 :(得分:2)
评论太大了所以我会把它放在这里。
听起来你正在以不正确的方式使用片段和AsyncTask。你永远不应该在doInBackground中做任何与UI相关的事情。
以下是您可以做的一个示例。
我假设以下情况:
方法是:
在您的片段中创建AsyncTask,如下所示:
private class LoadData extends AsyncTask<Void, Void, List<String>> {
ProgressDialog progressDialog;
//declare other objects as per your need
@Override
protected void onPreExecute()
{
// getActivity() is available in fragments and returns the activity to which it is attached
progressDialog= new ProgressDialog(getActivity());
progressDialog.setTitle("ProgressDialog Title");
progressDialog.setMessage("ProgressDialog Body");
progressDialog.setIndeterminate(true)
progressDialog.setCancelable(false)
progressDialog.show();
//do initialization of required objects objects here
};
@Override
protected Void doInBackground(Void... params)
{
List<String> results = new ArrayList<String>();
//do loading operation here
//add each of the texts you want to show in results
return results;
}
// onPostExecute runs on UI thread
@Override
protected void onPostExecute(List<String> results )
{
progressDialog.dismiss();
// iterate results and add the text to your TextViews
super.onPostExecute(result);
};
}
在片段的onCreate中启动AsyncTask:
@Override
public void onCreate(Bundle savedInstanceState) {
new LoadData().execute();
super.onCreate(savedInstanceState);
}
这样你就可以避免直接回调你的活动,这在你的场景中真的不需要(除非我误解了)。
否则请发布所有相关代码和布局。
答案 1 :(得分:1)
这一行:
我正在更新doInBackground方法中的TextViews
指出你的问题。您需要使用AsyncTask方法onProgressUpdate()
发布到UI线程。您不能直接致电onProgressUpdate()
,而是致电publishProgress()
。
有趣的是,我昨天在这里回答了类似的问题:android AsyncTask in foreach
它包含一个例子。
答案 2 :(得分:1)
这是你需要做的。
(1)从运行收集数据的代码的位置开始,首先应显示进度对话框。像这样:
busy = new ProgressDialog (this);
busy.setMessage (getString (R.string.busy));
busy.setIndeterminate (true);
busy.setCancelable (false);
busy.show();
(2)然后开始收集数据。这必须在一个单独的线程(或Runnable)中完成。做这样的事情:
Thread thread = new Thread ()
{
@Override
public void run()
{
try
{
... gather data ...
Message msg = handler.obtainMessage();
msg.what = LOADING_COMPLETE;
msg.obj = null;
handler.sendMessage (msg);
}
catch (Exception e)
{
Message msg = handler.obtainMessage();
msg.what = LOADING_FAILED;
msg.obj = e.getMessage(); // maybe pass this along to show to the user
handler.sendMessage (msg);
}
// get rid of the progress dialog
busy.dismiss();
busy = null;
}
}
(3)向活动添加处理程序,以便在数据收集完成时接收通知:
Handler handler = new Handler()
{
@Override
public void handleMessage (Message msg)
{
if (msg.what == LOADING_COMPLETE)
loadingComplete ();
else if (msg.what == LOADING_FAILED)
loadingFailed ((String)msg.obj);
}
};
(4)实现处理程序:
private void loadingComplete ()
{
...
}
private void loadingFailed (String errorMessage)
{
...
}
这是必需品。