Android - AsyncTask中ProgressDialog未显示

4
我有一个与之有关的 Android 应用程序存在问题。
基本上,进度对话框根本没有显示。我认为这是某种线程问题,但我不知道该如何解决它。
我正在使用 ActionBarSherlock 以及一些片段。我还使用了新的 Android DrawerLayout,在抽屉中有我的选项,当单击时替换片段。
在首次加载应用程序时,我想检查数据库以查看是否已下载初始数据。如果没有,则开始一个异步任务来下载数据。此过程应显示 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”。
谢谢。
2个回答

10

return new HttpConnection(activity).execute().get();中删除.get()。因为这样会锁定您的UI线程。删除后,AsyncTasks将按预期工作。

目的是要异步执行,所以boolean downloadData()应该返回void类型。如果您需要对数据进行处理,则应实现一个名为“listener”的接口并将其传递给AsyncTask。

示例Listener:

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);
}

0

我的问题不是像其他人一样在执行execute()方法后调用get()方法的常见问题。我的问题是我传递给AsyncTask方法的上下文。我有一个settingsActivity和一个ReadMeActivity,它调用了asynctask任务。我没有使用被调用的上下文(ReadMeActivity.this),而是使用了settingsActivity,这导致它无法被看到。一旦我切换并传递了活动被调用的上下文,它就可以工作了。

希望能帮助其他人。


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