0

I have a fragment activity and want to get data from my php script. I need this data to draw my ui effectively. My problem is my UI/fragment draws before i get data back, im not sure why as i fire it as early as i can in onCreate'. I put a dialog into pre and post to effectively freeze UI while data is retreived in background but....I dont see this happening, i think im too late in calling itas when the dialog appears during debug it shows ontop of a drawn screen which is baffling to me.

I have an alternative solution which is to fire the asyncTask in calling activity (previous activity) and pass result in bundle but i don't like this solution as its rigid and may cause issues with screen rotation.

I have been stuck on this for ages, can anybody tell me specifically where to put my async execute - the dialog should effectively make it a sync process. I have placed my asynctask everywhere i think possible/sensible and no luck.

In below i have the execute in the oncreate(). Note the execute doesnt d anything but update a test string which is "no change" beforehand, and "changed" in the postexecute so i can see what state its in at various points in code. It doesnt change before i draw my screen.

public class StaggeredGridActivityFragment extends FragmentActivity {


    String test ="not changed";
    private TilesAdapter mAdapter;
    private ArrayList<String> mData;
    private StaggeredGridView mGridView;

    private static final String TAG = "StaggeredGridActivityFragment";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        try
        {
            // Loading tile data in Background Thread
            new GetLoginTiles().execute();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar

        final FragmentManager fm = getSupportFragmentManager();

        // Create the list fragment and add it as our sole content.
        if (fm.findFragmentById(android.R.id.content) == null) {
            final StaggeredGridFragment fragment = new StaggeredGridFragment();
            fm.beginTransaction().add(android.R.id.content, fragment).commit();
        }
        Intent i=getIntent();
        Bundle extras = i.getExtras();
        String tmp = extras.getString("myKey");

    }


    private class StaggeredGridFragment extends Fragment implements AbsListView.OnScrollListener, AbsListView.OnItemClickListener {
                //private StaggeredGridView mGridView;
                private boolean mHasRequestedMore;
               // private TilesAdapter mAdapter;

                //private ArrayList<String> mData;

                @Override
                public void onCreate(final Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setRetainInstance(true);
                }

                @Override
                public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
                    return inflater.inflate(R.layout.activity_sgv, container, false);
                }

                @Override
                public void onActivityCreated(final Bundle savedInstanceState) {
                    List<NameValuePair> params = new ArrayList<NameValuePair>();

                    //Encapsulate all within a post cereate from a async task or call a blocking http call
                    super.onActivityCreated(savedInstanceState);

                    mGridView = (StaggeredGridView) getView().findViewById(R.id.grid_view);

                    if (savedInstanceState == null) {
                        final LayoutInflater layoutInflater = getActivity().getLayoutInflater();
                        View header = layoutInflater.inflate(R.layout.list_item_header_footer, null);
                        mGridView.addHeaderView(header);
                    }

                    if (mAdapter == null) {
                        mAdapter = new TilesAdapter(getActivity(), R.id.summary1_value);
                    }

                    if (mData == null) {
                        mData = ActivityTileData.getLoginTileDataArray(getActivity());
                    }


                    for (String data : mData) {
                        mAdapter.add(data); //Add each mData TileAdapter element to an mAdapter where it will be further broken down and used by the TileAdapter
                    }

                    mGridView.setAdapter(mAdapter);
                    mGridView.setOnScrollListener(this);
                    mGridView.setOnItemClickListener(this);
                }

                @SuppressLint("LongLogTag")
                @Override
                public void onScrollStateChanged(final AbsListView view, final int scrollState) {
                    Log.d(TAG, "onScrollStateChanged:" + scrollState);
                }

                @SuppressLint("LongLogTag")
                @Override
                public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) {
                    Log.d(TAG, "onScroll firstVisibleItem:" + firstVisibleItem +
                            " visibleItemCount:" + visibleItemCount +
                            " totalItemCount:" + totalItemCount);
                    // our handling
                    if (!mHasRequestedMore) {
                        int lastInScreen = firstVisibleItem + visibleItemCount;
                        if (lastInScreen >= totalItemCount) {
                            Log.d(TAG, "onScroll lastInScreen - so load more");
                            mHasRequestedMore = true;
                            onLoadMoreItems();
                        }
                    }
                }

                //Loads all of the objects from the getLoginTileData() if called
                private void onLoadMoreItems() {
                    while(mAdapter.getCount()<mData.size()) {
                        //final ArrayList<String> sampleData = SampleData.generateSampleData();
                        final ArrayList<String> loginTileData = ActivityTileData.getLoginTileDataArray(getActivity());
                        for (String data : loginTileData) {
                            mAdapter.add(data.toString());
                        }
                        // stash all the data in our backing store
                        mData.addAll(loginTileData);
                        // notify the adapter that we can update now
                        mAdapter.notifyDataSetChanged();
                        mHasRequestedMore = false;
                    }
                }

                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                    Toast.makeText(getActivity(), "Item Clicked: " + position, Toast.LENGTH_SHORT).show();
                }
            }
    // Progress Dialog
    private ProgressDialog qDialog;
    // JSON parser class
    JSONParser jParser = new JSONParser();
    String url_login ="http://xxx/xxx.php";
    /**
     * Background Async Task to Load all images by making HTTP Request
     * */
    class GetLoginTiles extends AsyncTask<String, String, String> {
        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            qDialog = new ProgressDialog(StaggeredGridActivityFragment.this);
            qDialog.setMessage("Please wait...");
            qDialog.setIndeterminate(false);
            qDialog.setCancelable(false);
            qDialog.show();
        }

        @Override
        protected String doInBackground(String... args) {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            // getting JSON string from URL
            JSONObject jsonLogin = jParser.makeHttpRequest(url_login, "GET", params);
            test=jsonLogin.toString();

            return jsonLogin.toString();
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String jsonString) {
            // dismiss the dialog after getting all questions
            qDialog.dismiss();
            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {
                    /**
                     * Updating parsed JSON data into imagebuttons
                     * */
                    test="local test has changed";
                }
            });

        }
    }
}
Dumbo
  • 13,555
  • 54
  • 184
  • 288
Fearghal
  • 10,569
  • 17
  • 55
  • 97

1 Answers1

0

I have an alternative solution which is to fire the asyncTask in calling activity (previous activity) and pass result in bundle but i don't like this solution as its rigid and may cause issues with screen rotation.

this is a good way to do it

override onSaveInstanceState to save the extras between rotations

also see here for more details

edit: it seems you are trying to change the text using

test="local test has changed";

whaat you need to do is pass the activity to the asynctask then

VIEWTYPEHERE button= ( VIEWTYPEHERE)  activity.findViewById(R.id.YOUR_VIEW"S_ID_HERE);

button.setText("");

a couple of notes

on post execute runs on ui thread you don't need a new runnable also you forgot to call .run() on it

Community
  • 1
  • 1
  • Hmmm ok. It seems messy but maybe that is the standard. Why cant i fire the async task in my oncreate and gett he data back before drawing starts? I do this in prev activity and it works no issue. – Fearghal Mar 31 '15 at 11:05
  • I don't think its a good idea to try and pause onCreate anyway call the async task in the previous activity show a progress dialog on pre and hide it on post and then pass the extras and start the activity if you keep the Async task as its own class its not messy at all i have a project with about 20 Async tasks and they all work that way – MetalDragon Mar 31 '15 at 11:09
  • Thx a mill for the advice. Good to hear im not a million miles off. Do you know per chance why my fragment activity refuses to pause at oncreate? – Fearghal Mar 31 '15 at 11:21
  • not sure, but I just realized its better to call it before the activity start this way its only called once and the data is passed around. if you call it in onCreate() it will be called every time the user rotates the screen so unless that is your desired behaviour leave it out of onCreate() – MetalDragon Mar 31 '15 at 11:30
  • What about the scenario where something updates and you want to update the current screen? – Fearghal Mar 31 '15 at 14:19
  • when i want to call the async in onCreate() i set the values of everything the async will update to place holders and block the ui with a progress dailog till the async finishes async doesn't pause onCreate() – MetalDragon Mar 31 '15 at 14:39