我有一个异步任务,它在执行任务时不会添加百分比。它始终保持在0%0/100
这是我的代码
private class getAppInfo extends AsyncTask<String, String, String> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
ProgressDialog dialog;
@Override
protected void onPreExecute() {
if(showLoading == true){
dialog = new ProgressDialog(SelfHelp.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage("Loading");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.setMax(100);
dialog.setProgress(100);
dialog.show();
}
}
@Override
protected String doInBackground(String... urls) {
String xml = null;
int count = 0;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(urls[0]);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
while(count != 100){
publishProgress(""+count);
count += 5;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Document doc = parser.GetDomElement(xml);
NodeList nl = doc.getElementsByTagName("topic");
getChildElements(nl);
return xml;
}
@Override
protected void onProgressUpdate(String... progress) {
Log.v("count",progress[0]);
dialog.setProgress(Integer.parseInt(progress[0]));
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
@Override
protected void onPostExecute(String result) {
//dialog.setProgress(100);
menuList.setAdapter(setListItems(menuItems));
menuList.setTextFilterEnabled(true);
if(showLoading == true){
dialog.dismiss();
showLoading = false;
}
}
确实进入onProgressUpdate
并且计数上升了5但进度条没有变化。如何将其增加5并正确显示进度?
答案 0 :(得分:26)
您的问题与setIndeterminate(true)
有关:如果您想要更新进度,则应将其设置为false
。如果你setIndeterminate(true)
那么ProgressDialog将作为经典的Windows沙漏
答案 1 :(得分:3)
您可以尝试以下代码,它显示%比率的进度,这是代码,
public class ProgressBarExampleActivity extends Activity
{
ProgressThread progThread;
ProgressDialog progDialog;
Button button1, button2;
int typeBar; // Determines type progress bar: 0 = spinner, 1 = horizontal
int delay = 1000; // Milliseconds of delay in the update loop
int maxBarValue = 30; // Maximum value of horizontal progress bar
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// // Process button to start spinner progress dialog with anonymous inner class
// button1 = (Button) findViewById(R.id.Button01);
// button1.setOnClickListener(new OnClickListener()
// {
// public void onClick(View v)
// {
// typeBar = 0;
// showDialog(typeBar);
// }
// });
// Process button to start horizontal progress bar dialog with anonymous inner class
button2 = (Button) findViewById(R.id.Button02);
button2.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
typeBar = 1;
showDialog(typeBar);
}
});
}
// Method to create a progress bar dialog of either spinner or horizontal type
@Override
protected Dialog onCreateDialog(int id)
{
switch(id)
{
// case 0: // Spinner
// progDialog = new ProgressDialog(this);
// progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
// progDialog.setMessage("Loading...");
// progThread = new ProgressThread(handler);
// progThread.start();
// return progDialog;
case 1: // Horizontal
progDialog = new ProgressDialog(this);
progDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progDialog.setMax(maxBarValue);
progDialog.setMessage("Dollars in checking account:");
progThread = new ProgressThread(handler);
progThread.start();
return progDialog;
default:
return null;
}
}
// Handler on the main (UI) thread that will receive messages from the
// second thread and update the progress.
final Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
// Get the current value of the variable total from the message data
// and update the progress bar.
int total = msg.getData().getInt("total");
progDialog.setProgress(total);
// if (total >= maxBarValue)
if (total <= 0 )
{
dismissDialog(typeBar);
progThread.setState(ProgressThread.DONE);
}
}
};
// Inner class that performs progress calculations on a second thread. Implement
// the thread by subclassing Thread and overriding its run() method. Also provide
// a setState(state) method to stop the thread gracefully.
private class ProgressThread extends Thread
{
// Class constants defining state of the thread
final static int DONE = 0;
final static int RUNNING = 1;
Handler mHandler;
int mState;
int total;
// Constructor with an argument that specifies Handler on main thread
// to which messages will be sent by this thread.
ProgressThread(Handler h)
{
mHandler = h;
}
// Override the run() method that will be invoked automatically when
// the Thread starts. Do the work required to update the progress bar on this
// thread but send a message to the Handler on the main UI thread to actually
// change the visual representation of the progress. In this example we count
// the index total down to zero, so the horizontal progress bar will start full and
// count down.
@Override
public void run()
{
mState = RUNNING;
total = maxBarValue;
while (mState == RUNNING)
{
// The method Thread.sleep throws an InterruptedException if Thread.interrupt()
// were to be issued while thread is sleeping; the exception must be caught.
try
{
// Control speed of update (but precision of delay not guaranteed)
Thread.sleep(delay);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread was Interrupted");
}
// Send message (with current value of total as data) to Handler on UI thread
// so that it can update the progress bar.
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total--; // Count down
}
}
// Set current state of thread (use state=ProgressThread.DONE to stop thread)
public void setState(int state)
{
mState = state;
}
}
}
参见输出,
答案 2 :(得分:1)
我将提到另一个方法,因为当我在寻找一些实用的方法时,我遇到了这个解决方案,如何从运行AsyncTask的Service回到主UI。 Lucifer的解决方案不是模块化的服务,如果你需要在1个以上的课程中使用你的服务(这是我的情况),你将无法访问变量处理程序,据我所知你甚至无法将Handler作为Intent to Service发送(您可以将其发送到AsyncTask tho)。解决方案是广播。
sendBroadcast(new Intent(WORK_DONE));
在AsyncTask和
中private BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context c, Intent i) { //update your UI here }
}
registerReceiver(receiver, new IntentFilter(WORK_DONE));
在您的活动中。
我不喜欢Android开发人员使用的所有内部类。我知道创建内部类和访问外部类变量更容易,但是一旦你需要再次使用该类,你的注定就会失败,你必须编辑代码!我真的是Android的新手,也许我错了,你实际上并不需要重用这些类。从来没有做过更大的项目,所以我不知道,但它感觉不对,因为在大学时,他们努力教我们如何编写可重用的代码。