在android中,为什么我的ProgressBar会冻结?
我在从服务器检索数据时显示进度条,从服务器检索数据后显示图表上的数据,但在绘制图表上的数据时,我的进度条冻结。有人知道为什么会这样吗 先谢谢你在android中,为什么我的ProgressBar会冻结?,android,progress-bar,Android,Progress Bar,我在从服务器检索数据时显示进度条,从服务器检索数据后显示图表上的数据,但在绘制图表上的数据时,我的进度条冻结。有人知道为什么会这样吗 先谢谢你 private ProgressDialog pd; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Toast.makeText(context, "Please Wa
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();
}
});
这是因为您甚至在关闭或关闭对话框之前就开始更新UI。这就是您的progressDialog冻结的原因 所以像这样修改代码
pd.dismiss();
runOnUiThread(t);
您应该借助(智能回退线程)和 AsyncTask允许正确且轻松地使用UI线程。此类允许在UI线程上执行后台操作和发布结果,而无需操纵线程和/或处理程序 异步任务由在后台线程上运行的计算定义,其结果在UI线程上发布。异步任务由3种通用类型(称为Params、Progress和Result)和4个步骤(称为begin、doInBackground、processProgress和end)定义 四个步骤 执行异步任务时,任务将经历4个步骤:
onPreExecute()
,在执行任务后立即在UI线程上调用。此步骤通常用于设置任务,例如在用户界面中显示进度条
doInBackground(Params…
,在onPreExecute()完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的背景计算。异步任务的参数被传递到此步骤。此步骤必须返回计算结果,并将返回到最后一步。此步骤还可以使用publishProgress(进度…)发布一个或多个进度单元。这些值在UI线程的onProgressUpdate(Progress…)步骤中发布
onProgressUpdate(Progress…
,在调用publishProgress(Progress…)后在UI线程上调用。执行的时间未定义。此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。例如,它可以用于制作进度条动画或在文本字段中显示日志
onPostExecute(Result)
,后台计算完成后在UI线程上调用。背景计算的结果作为参数传递到此步骤。
线程规则
要使此类正常工作,必须遵循一些线程规则:
必须在UI线程上创建任务实例。
必须在UI线程上调用execute(参数…)。
不要手动调用onPreExecute()、onPostExecute(结果)、doInBackground(参数…)和onProgressUpdate(进度…)。
该任务只能执行一次(如果尝试第二次执行,将引发异常)
示例代码适配器在本例中的作用并不重要,更重要的是要理解您需要使用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();
}
}
private类PrepareAdapter1扩展异步任务{
进程对话;
@凌驾
受保护的void onPreExecute(){
dialog=新建ProgressDialog(viewContacts.this);
setMessage(getString(R.string.please_wait_,while_loading));
对话框。setUndeterminate(true);
对话框。可设置可取消(false);
dialog.show();
}
/*(非Javadoc)
*@see android.os.AsyncTask#doInBackground(Params[])
*/
@凌驾
受保护的联系人列表光标或适配器doInBackground(无效…参数){
cur1=objItem.getContacts();
开始管理光标(cur1);
adapter1=新联系人列表光标或适配器(viewContacts.this,
R.layout.contact_for_listitem,cur1,新字符串[]{},新int[]{});
返回适配器1;
}
PostExecute上受保护的void(ContactsListCursorAdapter结果){
list.setAdapter(结果);
dialog.dismise();
}
}
记住android会在内存中保留dilogs的引用。这样它就不需要一次又一次地重新创建它。所以“进度”对话框第一次工作正常,但下一次挂起/卡住
注意:android不会清除dilogs的内存引用,即使在删除它们之后
有一个名为removeDialog(int-id)
的方法是Activity
类,它还将清除内存引用
下面是如何显示和删除对话框
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)
来隐藏它。我也面临同样的问题,我自己解决了
请看我的示例代码。你会明白的
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);
}
公共类NearByLoc扩展异步任务{
@SuppressLint(“InlinedApi”)
受保护的void onPreExecute(){
//pdailog.show();
加载_spinnerMain.setVisibility(View.VISIBLE);
}
@凌驾
受保护的Void doInBackground(Void…参数){
//在这里编写完整的代码[逻辑]
}
@凌驾
受保护的void onPostExecute(未使用的void){
//最后是适配器的数据设置列表
//在设置适配器之前,您应该关闭Progress spinnerr
加载_spinnerMain.setVisibility(View.GONE);
NearByMeAdapter=新的NearByMeAdapter(NearByMe.this,list);
listViewNearLoc.setAdapter(适配器);
}
这对我很有用。希望它能帮助你然后你必须在调用runOnUiThread(t)之前关闭旧对话框并启动新的进度对话框。我如何访问此AsyncTask子类中的“活动”视图我在preExecute中没有得到什么是viewContacts()是父类名称,包含