在android为什么我的ProgressBar冻结了?

时间:2011-11-30 07:07:33

标签: android progress-bar

我在从服务器检索数据时显示进度条,并且在从服务器检索数据后显示图表上的数据,但在绘制图表上的数据时,我的进度条被冻结,任何人都知道为什么会这样。 .....

提前感谢......

private ProgressDialog pd;
private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {        
        Toast.makeText(context, "Please Wait...", Toast.LENGTH_LONG).show();
        Thread t = new Thread(new Runnable() {              
            @Override
            public void run() {
                functionDrawMyData();/*in this function i am accessing activity view and drawing data on that view at time of drawing my Progress bar Freezes */
            }
        });
        runOnUiThread(t);
        pd.dismiss();           
    }
};  

我使用的这个处理程序在检索完数据后调用 按下按钮我将获取数据并显示进度条

ImageButton myButton = (ImageButton) findViewById(R.id.myBtn);
pair1ChartButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {               
                pd = ProgressDialog.show(v.getContext(),"Please wait...","Retrieving data ...",true,
                        true,
                        new DialogInterface.OnCancelListener(){
                            @Override
                            public void onCancel(DialogInterface dialog) {

                            }
                        });
                Thread t = new Thread(new Runnable() {                      
                    @Override
                    public void run() {
                            getDataFromServer();//calling function to get data from server
                        handler.sendEmptyMessage(0);                    
                    }
                });
                t.start();
        }
    });

4 个答案:

答案 0 :(得分:2)

记住android会将dilogs的引用保存在内存中。这样它就不需要一次又一次地重新创建它。因此,进度对话框第一次正常工作,但下次挂起/卡住。

注意:即使在解雇之后,android也不会清除dilogs的内存引用。

方法是Activity类,命名为removeDialog(int id),这也将清除内存引用。

以下是显示和删除对话框的方法

protected Dialog onCreateDialog(int id) {
        // TODO Auto-generated method stub
        switch(id){
          case 0:{
             dialog = ProgressDialog.show(this, "", 
                    "Loading. Please wait...", true);
             return dialog;
          }
             }

        return super.onCreateDialog(id);
    }

现在只需致电showDialog(0)以显示对话框,然后removeDialog(0)隐藏它。

答案 1 :(得分:1)

你应该在AsyncTask(智能背景线程)和ProgressDialog

的帮助下完成此操作

AsyncTask可以正确,轻松地使用UI线程。该类允许执行后台操作并在UI线程上发布结果,而无需操纵线程和/或处理程序。

异步任务由在后台线程上运行的计算定义,其结果在UI线程上发布。异步任务由3种泛型类型定义,称为Params,Progress和Result,以及4个步骤,分别称为begin,doInBackground,processProgress和end。

4个步骤

执行异步任务时,任务将经历4个步骤:

onPreExecute(),在执行任务后立即在UI线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

doInBackground(Params...),在onPreExecute()完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数将传递给此步骤。计算结果必须由此步骤返回,并将传递回最后一步。此步骤还可以使用publishProgress(Progress ...)发布一个或多个进度单元。这些值发布在UI线程的onProgressUpdate(Progress ...)步骤中。

onProgressUpdate(Progress...),在调用publishProgress(Progress ...)后在UI线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。例如,它可用于为进度条设置动画或在文本字段中显示日志。

onPostExecute(Result),在后台计算完成后在UI线程上调用。背景计算的结果作为参数传递给该步骤。 线程规则

此课程必须遵循一些线程规则才能正常使用:

必须在UI线程上创建任务实例。 必须在UI线程上调用execute(Params ...)。 不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...)。 该任务只能执行一次(如果尝试第二次执行,则会抛出异常。)

示例代码
适配器在此示例中的作用并不重要,更重要的是要了解您需要使用AsyncTask来显示进度的对话框。

private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > {
    ProgressDialog dialog;
    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(viewContacts.this);
        dialog.setMessage(getString(R.string.please_wait_while_loading));
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }
    /* (non-Javadoc)
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected ContactsListCursorAdapter doInBackground(Void... params) {
        cur1 = objItem.getContacts();
        startManagingCursor(cur1);

        adapter1 = new ContactsListCursorAdapter (viewContacts.this,
                R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {});

        return adapter1;
    }

    protected void onPostExecute(ContactsListCursorAdapter result) {
        list.setAdapter(result);
        dialog.dismiss();
    }
}

答案 2 :(得分:0)

这是因为您甚至在关闭或关闭对话框之前就开始更新UI。这就是你的progressDialog冻结的原因。

所以改变你的代码,

     pd.dismiss();  
    runOnUiThread(t);

答案 3 :(得分:0)

同样的问题我也面对,我解决了自己,

看看我的示例代码。你会明白的。

public class NearByLoc extends AsyncTask<Void, Void, Void> {
    @SuppressLint("InlinedApi")
    protected void onPreExecute() {

        // pdailog.show();
        loading_spinnerMain.setVisibility(View.VISIBLE);
    }


@Override
    protected Void doInBackground(Void... params) {
     //write your entire code [logic]here

  }
@Override
    protected void onPostExecute(Void unused) {

        //finally list of data setting to the adapter
        //before setting to the adapter you should dismiss Progress spinnerr 

        loading_spinnerMain.setVisibility(View.GONE);
        NearByMeAdapter adapter = new NearByMeAdapter(NearByMe.this, list);

        listViewNearLoc.setAdapter(adapter);
}

它为我工作..希望它可以帮助你