在UI线程中阻塞的doInBackground调用AsyncTask,然后休眠。

4
我有一个活动,由AsyncTask组成,旨在在用户点击按钮时启动请求。我一直在寻找答案,但没有找到相同的问题,或者对我来说不一样。代码正在做我想要的事情,但ProgressDialog看起来被阻塞了,因为旋转器有时不会转动(几乎所有时间都是如此)。
当我点击按钮时:
AsyncTask被启动 - > onPreExecute中调用showDialog() - > startSearch(SearchManager启动新的AsyncTask,在doInBackground中有一个带有网络的重要调用) - > Activity中的doInBackground等待SearchManager被加载 - >显示。
button_search.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                new SearchTask().execute();

            }
        });

在搜索活动中使用异步任务的代码:

private class SearchTask extends AsyncTask<Void,Void,Void>{

        @Override
        protected void onPreExecute(){
            showDialog(DIALOG_LOADING_ID);

            searchManager.startSearch();
        }

        @Override
        protected Void doInBackground(Void... params) {


            while(searchManager.isLoading()){
                try {Thread.sleep(150);} catch(Exception e){};
            }


            return null;
        }

        @Override
        protected void onPostExecute(Void ret){
            try {dismissDialog(DIALOG_LOADING_ID);} catch (Exception e){};

            if ( searchManager.errorOccurred() ){
                //Error
            } else {
                //No Error

            }   
        }

搜索管理器异步任务的代码:这是由startSearch直接启动的

protected class SearchAsync extends AsyncTask <Void,Void,Void>{

        @Override
        protected Void doInBackground(ComSearchAds... datas) {
            global.getDataManager().doSearch();
                        //... When finished
                        setIs_loading(false);
                }
}

我看起来似乎做错了什么,但是找不到错误在哪里以及如何避免这种情况。谢谢你的帮助! 解决方案: 最后,似乎原因是我在使用同一 ProgressDialog 实例导致进度对话框无法旋转。
showDialog(DIALOG_LOADING_ID); 
//doInBackground
dismissDialog(DIALOG_LOADING_ID);

使用 causes 会导致问题,我改成了


removeDialog(DIALOG_LOADING_ID)

现在它正常运作。感谢大家,希望能有所帮助!


2
searchManager.startSearch(); 在 preExecute 中!应该在 doInBackground 中。 - Sherif elKhatib
为什么需要在onPreExecute中启动另一个AsyncTask?为什么不直接在SearchTaskdoInBackground()中运行global.getDataManager().doSearch(); - Vladimir
1
@Sherif 不是这样的,AsyncTask 应该从 UI 线程初始化和调用。 - Vladimir
@Vladimir,阻塞进程的唯一解释是该函数正在阻塞。 - Sherif elKhatib
1
你在真实设备上测试过吗? - Lalit Poptani
显示剩余4条评论
3个回答

0

你能否尝试在你的布局文件中添加一个ProgressBar控件,并在开始异步任务时将其Visible设置为true,当进程结束时将其设置为gone。以下是相应的代码。

<ProgressBar 
android:layout_width="wrap_content" 
android:id="@+id/progressBar1" 
android:layout_height="wrap_content"></ProgressBar>

0

很难说,但是尝试使用这个onClickListner:

button_search.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        new SearchTask().execute();
        setIs_loading(true);
        searchManager.startSearch(); 
    }
});

这只是一个猜测,但也许会奏效


它正在做完全相同的事情,就像以前一样 ;) - Camille R

0

你不需要创建另一个任务,只需在同一活动中执行搜索操作即可。

你所需要做的就是将搜索代码放入搜索任务的doInBackground()方法中。例如:

@Override
protected Void doInBackground(Void... params) {

    global.getDataManager().doSearch();
    return null;
}

还可以使用类级别变量来获取搜索结果并存储为true/false

@Override
        protected void onPostExecute(Void ret){

            // Set you result here
            setIs_loading(my_searh_result);

            try {dismissDialog(DIALOG_LOADING_ID);} catch (Exception e){};

            if ( searchManager.errorOccurred() ){
                //Error
            } else {
                //No Error

            }   
        }

好的,我没有创建第二个异步任务,而是将网络相关的内容放在了searchManager.startSearch()中,并将调用放在了doInBackground中,但是旋转器仍然没有转动。 - Camille R
1
分享你的完整代码,你是如何展示旋转器的?你使用旋转对话框吗?ProgressDialog ProgressIndicator = ProgressDialog.show(mContext, null , "加载中", true); - Arslan Anwar
是的,你说得对,那就是问题所在!dismiss删除动画。 - Camille R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接