AsyncTask 完成后才会显示 ProgressDialog

发布于 2024-08-30 14:45:17 字数 2666 浏览 7 评论 0原文

我试图显示一个不确定的 ProgressDialog,而 AsyncTask 绑定到 RemoteService。 RemoteService 在首次创建服务时构建用户联系人列表。对于一长串联系人,这可能需要 5~10 秒。

我遇到的问题是,在 RemoteService 构建其联系人列表之前,ProgressDialog 不会显示。我什至尝试放入 Thread.sleep 来给 ProgressDialog 有时间显示。使用 sleep 语句,ProgressDialog 会加载并开始旋转,但一旦 RemoteService 开始工作就会锁定。

如果我只是将 AsyncTask 变成虚拟代码,并让它休眠一段时间,一切都会正常。但是当任务必须执行实际工作时,UI 就像只是坐着等待。

对我做错了什么有什么想法吗?

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(IM,"Start Me UP!!");
    setContentView(R.layout.main);
    Log.d(IM, "Building List View for Contacts");
    restoreMe();
     if (myContacts==null){
         myContacts = new ArrayList<Contact>();
         this.contactAdapter = new ContactAdapter(this, 
                                                  R.layout.contactlist, 
                                                  myContacts);
         setListAdapter(this.contactAdapter);
         new BindAsync().execute();
     }
     else{
         this.contactAdapter = new ContactAdapter(this, 
                                                  R.layout.contactlist, 
                                                  myContacts);
         setListAdapter(this.contactAdapter);

     }
}

private class BindAsync extends AsyncTask<Void, Void, RemoteServiceConnection>{
    @Override
    protected void onPreExecute(){
        super.onPreExecute();
        Log.d(IM,"Showing Dialog");
        showDialog(DIALOG_CONTACTS);
    }
    @Override
    protected RemoteServiceConnection doInBackground(Void... v) {
        Log.d(IM,"Binding to service in BindAsync");
        try{
        Thread.sleep(2000);
        } catch (InterruptedException e){

        }

        RemoteServiceConnection myCon;
        myCon = new RemoteServiceConnection();
        Intent i = new Intent(imandroid.this,MyRemoteService.class);
       bindService(i, myCon, Context.BIND_AUTO_CREATE);
        startService(i);
        Log.d(IM,"Bound to remote service");
        return myCon;
    }
    @Override
    protected void onPostExecute(RemoteServiceConnection newConn){
        super.onPostExecute(newConn);
        Log.d(IM,"Storing remote connection");
        conn=newConn;
    }

};

编辑:添加了 onCreateDialog

 protected Dialog onCreateDialog(int id){
    switch(id){
    case DIALOG_CONTACTS:
        ProgressDialog progDialog = new ProgressDialog(imandroid.this);
        progDialog.setMessage("Loading Contacts... Please Wait");
        progDialog.setCancelable(false);
        return progDialog;
    default:
        return super.onCreateDialog(id);
    }
}

I am trying to display an indefinite ProgressDialog, while an AsyncTask binds to a RemoteService. The RemoteService builds a list of the users contacts when the service is first created. For a long list of contacts this may take 5~10 seconds.

The problem I am having, is that the ProgressDialog does not display until after the RemoteService has built it's list of contacts. I even tried putting a Thread.sleep in to give the ProgressDialog time to show up. With the sleep statement the ProgressDialog loads and starts spinning, but then locks up as soon as the RemoteService starts doing it's work.

If I just turn the AsyncTask into dummy code, and just let it sleep for a while, everything works fine. But when the task has to do actual work, it is like the UI just sits and waits.

Any ideas on what Im doing wrong ?

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(IM,"Start Me UP!!");
    setContentView(R.layout.main);
    Log.d(IM, "Building List View for Contacts");
    restoreMe();
     if (myContacts==null){
         myContacts = new ArrayList<Contact>();
         this.contactAdapter = new ContactAdapter(this, 
                                                  R.layout.contactlist, 
                                                  myContacts);
         setListAdapter(this.contactAdapter);
         new BindAsync().execute();
     }
     else{
         this.contactAdapter = new ContactAdapter(this, 
                                                  R.layout.contactlist, 
                                                  myContacts);
         setListAdapter(this.contactAdapter);

     }
}

private class BindAsync extends AsyncTask<Void, Void, RemoteServiceConnection>{
    @Override
    protected void onPreExecute(){
        super.onPreExecute();
        Log.d(IM,"Showing Dialog");
        showDialog(DIALOG_CONTACTS);
    }
    @Override
    protected RemoteServiceConnection doInBackground(Void... v) {
        Log.d(IM,"Binding to service in BindAsync");
        try{
        Thread.sleep(2000);
        } catch (InterruptedException e){

        }

        RemoteServiceConnection myCon;
        myCon = new RemoteServiceConnection();
        Intent i = new Intent(imandroid.this,MyRemoteService.class);
       bindService(i, myCon, Context.BIND_AUTO_CREATE);
        startService(i);
        Log.d(IM,"Bound to remote service");
        return myCon;
    }
    @Override
    protected void onPostExecute(RemoteServiceConnection newConn){
        super.onPostExecute(newConn);
        Log.d(IM,"Storing remote connection");
        conn=newConn;
    }

};

EDIT: Added onCreateDialog

 protected Dialog onCreateDialog(int id){
    switch(id){
    case DIALOG_CONTACTS:
        ProgressDialog progDialog = new ProgressDialog(imandroid.this);
        progDialog.setMessage("Loading Contacts... Please Wait");
        progDialog.setCancelable(false);
        return progDialog;
    default:
        return super.onCreateDialog(id);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

塔塔猫 2024-09-06 14:45:17

不要从 doInBackground() 执行 bindService()。首先,它几乎是瞬时的,因此您不需要将其放在后台线程中——您所做的只是浪费 CPU 时间和电池。其次,它需要与 LooperContext 的消息队列一起工作,因此将其放在后台线程中是危险的恕我直言。

另请注意,您既绑定到服务又启动服务。在某些情况下这是合适的,但通常您只需要其中之一。

Do NOT do a bindService() from doInBackground(). First, it is nearly instantaneous, so you do not need to have it in a background thread -- all you are doing is wasting CPU time and battery. Second, it needs to work with the Looper and message queue for your Context, and so putting it in a background thread is dangerous IMHO.

Also note that you are both binding to the service and starting the service. There are a few cases where that is appropriate, but normally you only need one or the other.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文