Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - progressdialog not displaying in AsyncTask

I have an android app that I am having trouble with.

Basically the ProgressDialog is not showing at all. I believe this to be a threading issue of some sort but I don't know how to fix it.

I am using ActionBarSherlock with some Fragments. I am also using the new Android DrawerLayout where I have my options on the drawer, which replace a fragment when clicked.

On first load of my app, I want to check the database to see if the inital data has been downloaded. If not, then I go off and begin an AsyncTask to download the data. This SHOULD have a ProgressDialog display during this, but it doesnt.

Can someone see where I am going wrong? Thanks.

MainScreen - The default landing page/fragment when the app opens

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() - The method that initiates the download

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

and finally NetworkManager.downloadData() - The method that kicks off the 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();
        }
    }

Using the above code, all I get is a white screen as the app tries to load, and sometimes an ANR. When the download is done, the fragment loads. So it works fine except for the missing ProgressDialog.

PS, Notice I'm setting the activity in each constructor.

Thanks.

like image 318
eoinzy Avatar asked Dec 25 '22 22:12

eoinzy


1 Answers

Remove .get() from return new HttpConnection(activity).execute().get(); You are basically locking your UI thread. Once removed it should work as AsyncTasks are expected to work.

The purpose is to be Asynchronous so boolean downloadData() should have a return type of void. If you need to do something with the data then you should implement an interface "listener" and pass it to the AsyncTask.

Example 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);
}
like image 188
JRomero Avatar answered Jan 09 '23 15:01

JRomero