Search code examples
javaandroidarraylistandroid-activitybackground-process

doInBackground does not run inside Activity onCreate


What I have : I have a SearchActivity which receives an ArrayList (NameDesSearch) from a fragment(after a button click) and it updates a simple listview. When I click a list view item a new view is appearing by the corresponding object (orgDesObj) of the clicked list item. This functionality works well.

Currently receiving list (NameDesSearch) consists of names and descriptions. All are strings.

But, I wanted to show lists names only. Hence I tried creating a function (titlefunc()). Here a new ArrayList ( NameDesTitles ) was crated to add relevent names only.

Issue: But, seems like Do In background function is not working by the time I call titlefunc().

Attempts: I put several Log to capture the point. I'm using the same function (getLocDesOb()) in the list view on item clicked as well. Surprisingly it works, even the doInBackground function also works. But when the search activity creates and titlefunc() is called, search list (finalODescriptionArrayList) in doInBackground is empty(). Form the Logs I receive the content of finalODescriptionArrayList as [] and size as 0. But, when I click list view item finalODescriptionArrayList updates.

I even tried by moving NameDesSearch = getIntent().getStringArrayListExtra("searched"); outside of the function as well.

Seems like my doInBackground method is calling only when the list item clicked but not activity on creates. Every other function works well. I'm not sure by the time when why my titlefunc() is called, why finalODescriptionArrayList does not update.

I would appreciate any suggestions on this. Thank you !

My Code: I have removed Logs for clearness.

public class SearchActivity extends AppCompatActivity {

    ListView searchedListView;
    String SearchedWord;
    private ArrayAdapter<String> orgAdapter;
    ArrayList<String> NameDesSearch = new ArrayList<String>();
    ArrayList<String> NameDesTitles = new ArrayList<String>();
    private OService OService;
    ArrayList<ODescription> finalODescriptionArrayList = new ArrayList<ODescription>();

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        searchedListView = (ListView) findViewById(R.id.searched_list_view);
        new GetCourse().execute();

        titlefunc();

        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, NameDesTitles);
        searchedListView.setAdapter(arrayAdapter);

        searchedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String selectedItemText = parent.getItemAtPosition(position).toString();
                ODescription orgDesObj = getLocDesOb(selectedItemText);
                if (orgDesObj != null) {

                    Intent intent = new Intent(SearchActivity.this, View.class);
                    intent.putExtra("sOb", orgDesObj);
                    startActivity(intent);
                }
            }
        });
    }

    @SuppressLint("StaticFieldLeak")
    private class GetCourse extends AsyncTask<Void, Void, Void> {

        @TargetApi(Build.VERSION_CODES.N)
        @Override
        protected Void doInBackground(Void... voids) {
            try {
                finalODescriptionArrayList = JsontoObject.jsonToObjectData(getResources().openRawResource(R.raw.newdb));

            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    public ODescription getLocDesOb(String selectedItemText) {

        if (finalODescriptionArrayList == null) {
            return null;
        }
        for (ODescription locDescObj : finalODescriptionArrayList) {
            if (locDescObj.getName().equals(selectedItemText) || locDescObj.getDescription().equals(selectedItemText)) {
                return locDescObj;
            }
        }
        return null;
    }

    public void titlefunc() {
        NameDesSearch = getIntent().getStringArrayListExtra("searched");
        for (String searchNameDes : NameDesSearch) {
            ODescription orgDesObj2 = getLocDesOb(searchNameDes);
            if (orgDesObj2 != null) {

                NameDesTitles.add(orgDesObj2.getName());
            }
        }
    }
}

Attempts After Answer Below AsyncTask update with onPostExecute. Then Since it take a little bit of time a progress bar added with onPreExecute. titlefunc() in oncreate method removed.

This method works now. But, sometimes the same issue exists. Arraylist to adapter is empty so that listview is empty. Seems like still taking lot of time to do the background task.

Updated AsyncTask

    @SuppressLint("StaticFieldLeak")
    private class GetCourse extends AsyncTask<Void, Void, Void> {
ProgressDialog progressDialog;

@Override
protected void onPreExecute() {
    super.onPreExecute();
    progressDialog = new ProgressDialog(SearchActivity.this);
    progressDialog.setMessage("Searching");
    progressDialog.setCancelable(false);
    progressDialog.show();
}
        @TargetApi(Build.VERSION_CODES.N)
        @Override
        protected Void doInBackground(Void... voids) {
            try {
                finalODescriptionArrayList = JsontoObject.jsonToObjectData(getResources().openRawResource(R.raw.newdb));

            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    titlefunc();
    arrayAdapter.notifyDataSetChanged();
    if (progressDialog.isShowing())
        progressDialog.dismiss();
}
   }

Modifed titlefunc() - to remove duplicates

Set<String > set = new HashSet<>( NameDesTitles);
NameDesTitles.clear();
NameDesTitles.addAll(set);

Solution

  • Your AsyncTask runs asynchronously, in the background. It will (most likely) not be finished when you call titleFunc() (which is what you are seeing).

    You can fix this in many ways. One way would be to update the content of your adapter after the AsyncTask completes. You can do this in onPostExecute() of your AsyncTask which will be called when the background processing completes. In that method you can run your titleFunc() or something similar to filter the results you want to display. You then need to tell your Adapter to update the view by calling notifyDatasetChanged() on the Adapter.