【问题标题】:Android - progressdialog not displaying in AsyncTaskAndroid - 进度对话框未显示在 AsyncTask 中
【发布时间】:2016-02-05 02:21:23
【问题描述】:

我有一个遇到问题的 Android 应用程序。

基本上ProgressDialog 根本没有显示。我认为这是某种线程问题,但我不知道如何解决。

我正在使用ActionBarSherlock 和一些Fragments。我还在使用新的 Android DrawerLayout,在抽屉里有我的选项,点击时会替换片段。

第一次加载我的应用程序时,我想检查数据库以查看初始数据是否已下载。如果没有,那么我开始使用AsyncTask 下载数据。在此期间应该有一个ProgressDialog 显示,但它没有。

有人能看出我哪里出错了吗?谢谢。

MainScreen - 应用打开时的默认登录页面/片段

public class MainScreen extends SherlockFragment {
    public static final String TAG = "MainScreen";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.activity_main, container, false);
        setHasOptionsMenu(false);

        ImageView imgLogo = (ImageView) rootView.findViewById(R.id.imgMainScreen);
        imgLogo.setOnClickListener(new ButtonHandler(getActivity()));

        checkDatabase();
        return rootView;
    }

    private void checkDatabase() {
        //Ensure there is data in the database
        DBHelper db = new DBHelper(this.getSherlockActivity());
        db.checkDatabase();
    }
...
}

DBHelper.checkDatabase() - 启动下载的方法

public void checkDatabase() {
    if (isEmpty()) {
        //Connect to net and download data
        NetworkManager nm = new NetworkManager(activity);
        if (!nm.downloadData()) {
            Toast.makeText(activity, R.string.internetCheck, Toast.LENGTH_SHORT).show();
        }
    }
}

最后 NetworkManager.downloadData() - 启动AsyncTask的方法:

   public boolean downloadData() {
        try {
            return new HttpConnection(activity).execute().get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return false;
    }

    public class HttpConnection extends AsyncTask<Void, Void, Boolean> {
        private ProgressDialog progressDialog;
        private Activity m_activity;

        protected HttpConnection(Activity activity) {
            m_activity = activity;
        }

        @Override
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(m_activity);
            progressDialog.setMessage("Wait ...");
            progressDialog.setCancelable(false);
            progressDialog.setMax(100);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.show();

            super.onPreExecute();
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            String[] types = new String[]{"type1", "type2", "type3", "type4", };
            StringBuilder sb = new StringBuilder();

            for(String type : types) {
                sb = new StringBuilder();
                if(DBHelper.TYPE4_TABLE.equals(type)) {
                    InputStream is = activity.getResources().openRawResource(R.raw.dbdata);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    try {
                        sb.append(reader.readLine());
                    } catch (IOException e) {
                        Toast.makeText(activity.getApplicationContext(), "Error retriveving data", Toast.LENGTH_SHORT).show();
                        Log.e(Constants.TAG, "Error reading data");
                        e.printStackTrace();
                    }
                } else {
                    sb = fetchURLData(Constants.ALL_URL+type);
                }
                cleanDataAndStore(sb, type);
            }

            return true;
        }

        @Override
        protected void onPostExecute(Boolean result){
              progressDialog.hide();
        }
    }

使用上面的代码,我得到的只是应用程序尝试加载时出现的白屏,有时还会出现 ANR。下载完成后,片段加载。所以它工作正常,除了缺少ProgressDialog

PS,请注意我在每个构造函数中设置了activity

谢谢。

【问题讨论】:

    标签: android multithreading android-asynctask progressdialog


    【解决方案1】:

    return new HttpConnection(activity).execute().get(); 中删除.get() 您基本上是在锁定您的UI 线程。删除后,它应该像预期的 AsyncTask 一样工作。

    目的是异步的,所以boolean downloadData() 的返回类型应该是void。如果您需要对数据做一些事情,那么您应该实现一个接口“监听器”并将其传递给 AsyncTask。

    监听器示例:

    class TaskConnect extends AsyncTask<Void, Void, ConnectionResponse> {
    
        private final AsyncTaskListener mListener;
    
        /**
         *
         */
        public TaskConnect(AsyncTaskListener listener) {
            ...
            mListener = listener;
        }
    
        @Override
        protected void onPreExecute() {
            if (mListener != null) {
                mListener.onPreExecute(mId);
            }
        }
    
        @Override
        protected ConnectionResponse doInBackground(Void... cData) {
            ...
            return responseData;
        }
    
        @Override
        protected void onPostExecute(ConnectionResponse response) {
            if (mListener != null) {
                mListener.onComplete(response);
            } else {
                LOG.w("No AsyncTaskListener!", new Throwable());
            }
        }
    }
    
    public interface AsyncTaskListener {
        public abstract void onPreExecute(int id);
        public abstract void onComplete(ConnectionResponse response);
    }
    

    【讨论】:

    • @J.Romero 真的很有帮助 +1
    【解决方案2】:

    我的问题不是其他人在 execute() 方法之后调用 get() 方法的常见问题。我的问题是我传递给我的 AsyncTask 方法的上下文。我有一个 settingsActivity,我有一个调用 asynctask 任务的 ReadMeActivity。我没有使用正在调用的上下文(ReadMeActivity.this),而是使用了阻止它被看到的 settingsActivity。一旦我切换它并传递给它调用活动的上下文,它就起作用了。

    希望对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-15
      • 2019-12-31
      • 1970-01-01
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      相关资源
      最近更新 更多