0

In my program a number of values are stored on the server. I read these data using of the AsyncTask class from the server.

This is my code:

public class TestActivity extends AppCompatActivity {
    private static List<String> mPackName;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mPackName = new ArrayList<>();
        try {
            boolean check = new GetDataAsyncTask().execute("1234567").get();
        } catch (InterruptedException e) {

        } catch (ExecutionException e) {
            e.printStackTrace();
            e.printStackTrace();
        }

    }

    private class GetDataAsyncTask extends AsyncTask<String, Void, Boolean> {

        @Override
        protected Boolean doInBackground(String... params) {
            final String mCode = params[0];

            APIGettingPosts apiGettingPosts = new APIGettingPosts(TestActivity.this, "get_off_code.php");
            apiGettingPosts.getOffCode(new APIGettingPosts.OnOffCodeReceived() {
                @Override
                public void onReceived(List<Posts> posts) {
                    if (!(posts == null || posts.isEmpty()))
                        for (int i = 0; i < posts.size(); ++i) {
                            mPackName.add(posts.get(i).getTitle());
                            Log.e("mPackName["+String.valueOf(i)+"]",mPackName.get(i));
                        }
                }
            });
            Log.e("Size of mPackName: ", String.valueOf(mPackName.size()));

            for (int i = 0; i < mPackName.size(); ++i)
                if (mCode.equals(mPackName.get(i))) {
                    Log.e("Is Equal: ", mPackName.get(i));
                    return true;
                }
            return false;
        }
    }
}

The program correctly receives the data from the server and stores it in the mPackName list. At the end of the doInBackground function, the program checks if the input value in the GetDataAsyncTask().execute("1234567") function exists in the mPackName list, returns the true value.

Although the input value of the GetDataAsyncTask().execute("1234567") function is in the mPackNamelist, the program returns the false value.

The Log cat output is as follows:

08-28/com.green E/Size of mPackName:: 0

08-28/com.green E/mPackName[0]: 1234567

08-28/com.green E/mPackName[1]: QAZXSWE

08-28/com.green E/mPackName[2]: QWERTYU

The size of the mPackName list is also zero in Log cat , although it has three values {'1234567','QAZXSWE','QWERTYU'}.

The question is: How do I search '1234567' value in the mPackName list to return the true value in check = new GetDataAsyncTask().execute("1234567").get(); code?

Community
  • 1
  • 1
Saeed
  • 3,294
  • 5
  • 35
  • 52
  • I think in the _doInBackground_ method, the program is not compiled linearly. Since in the _doInBackground_ method, we are waiting for the data from the server. The size of 0 of list is first seen and the program waits for the whole data to be called from the server. – Saeed Aug 29 '18 at 18:52
  • Yes and no... yes doInBackground does run on a background thread but I'm guessing APIGettingPosts apiGettingPosts = new APIGettingPosts(...) is also running on a separate background thread. So your log statement is executing before onReceived has been called. – tgrable Aug 29 '18 at 19:02

2 Answers2

3

Edited Answer

Looks like you even don't need AsyncTask as getOffCode method already runs in background thread.

Remove GetDataAsyncTask class and create a method like below.

private void search(final SearchCallback callback) {
    APIGettingPosts apiGettingPosts = new APIGettingPosts(TestActivity.this, "get_off_code.php");
    apiGettingPosts.getOffCode(new APIGettingPosts.OnOffCodeReceived() {
        @Override
        public void onReceived(List<Posts> posts) {
            if (!(posts == null || posts.isEmpty())) {
                for (int i = 0; i < posts.size(); ++i) {
                    mPackName.add(posts.get(i).getTitle());
                    Log.e("mPackName[" + String.valueOf(i) + "]", mPackName.get(i));
                    if (mCode.equals(mPackName.get(i))) {
                        callback.onSearchFound(true);
                        break;
                    }
                }
            }
            callback.onSearchFound(false);
        }
    });
}

public interface SearchCallback{
    void onSearchFound(boolean success);
}

Then call from onCreate method like below

search(new SearchCallback(){
    @Override
    public void onSearchFound(boolean success) {

    }
});
Krishna Sharma
  • 2,828
  • 1
  • 12
  • 23
1

Try placing a switch in the onPostExecute() method.

EG.

...

private class GetDataAsyncTask extends AsyncTask<String, Void, Boolean> {

@Override
void onPostExecute(Object o){
    handleResults()
}

...

void handleResults(){
// Insert your check here
}
miversen33
  • 573
  • 5
  • 19
  • On post execute is called after your execute method finishes. If this does not work, there is something else wrong. You might check out this wonderful write up https://stackoverflow.com/a/12575319/2104990 It explains how to get information from your AsyncTask properly – miversen33 Aug 29 '18 at 19:06