0

I've searched everywhere but could not find an answer which would fit my case. Here's the thing: I have a fragment which shows a view pager with two other fragments, both these fragments use asynctask to get information from a Parse.com database. The reason why I use asynctask is only to show a progress bar while the app gets data from parse. My problem is: whenever I change orientation to landscape (or vice-versa) while the "Do in background" method, the app crashes. What I would like to do is to keep the asynctask process running regardless of orientation changes, is that possible?

P.S: I've tried putting "setRetainInstance(true)" on the parentFragment but it didn't do the trick. And when I put "setRetainInstance(true)" on the fragements inside view pager, I get a force close.

Here's my fragment 1 on view pager (NewsFragment):

public class NewsFragment extends Fragment {

(...)

public NewsFragment() {
    // Required empty public constructor
}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment

    View fragmentView = inflater.inflate(R.layout.fragment_news, container, false);
    mListView = (ListView) fragmentView.findViewById(R.id.MyListView);
    mListView.addFooterView(new View(getActivity()), null, false);
    mListView.addHeaderView(new View(getActivity()), null, false);
    new RemoteDataTask().execute();



   (...)

            return fragmentView;
        }

// RemoteDataTask AsyncTask
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();


    }

    @Override
    protected Void doInBackground(Void... params) {
        // Create the array


        mProductsList = new ArrayList<Product>();
        try{

            ParseQuery<ParseObject> query = ParseQuery.getQuery("Products");
            query.orderByDescending("createdAt");
            query.setCachePolicy(ParseQuery.CachePolicy.NETWORK_ELSE_CACHE);
            ob = query.find();
            for (ParseObject parseObject : ob) {
                       // Locate images in flag column


                String title = (String) parseObject.get("title");
                String descrip = (String) parseObject.get("descrip");
                preco = (String) parseObject.get("preco");
                String data = (String) parseObject.get("data");
                String detail = (String) parseObject.get("detail");
                user = (String) parseObject.get("user");
                imagefile = parseObject.getParseFile("foto");
                if (imagefile!=null){
                    imageUrl = parseObject.getParseFile("foto").getUrl();
                }
                productId = parseObject.getObjectId();

                product = new Product(title, descrip, preco, data, detail, user, imagefile, imageUrl, productId);



                mProductsList.add(product);

            }
        } catch (ParseException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }

        return null;
    }




    @Override
    protected void onPostExecute(Void result) {
        // Locate the listview in listview_main.xml
        mListView.setAdapter(new MyAdapter());
        loadpd = (ProgressBar) getView().findViewById(R.id.loadpd);
        getView();
        loadpd.setVisibility(View.INVISIBLE);



    }
}(...)}

Here's my fragment 2 on view pager (UserProductsFragment)

public class UserProductsFragment extends Fragment {

(...)
public UserProductsFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    setHasOptionsMenu(true);
    // Inflate the layout for this fragment
    View fragmentView = inflater.inflate(R.layout.fragment_news_user, container, false);
    mListView = (ListView) fragmentView.findViewById(R.id.MyUserListView);
    mListView.addFooterView(new View(getActivity()), null, false);
    mListView.addHeaderView(new View(getActivity()), null, false);
    new RemoteDataTask().execute();


    return fragmentView;
}

private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();



    }

    @Override
    protected Void doInBackground(Void... params) {
        // Create the array


        if (currentUser != null) {
        userid= currentUser.getObjectId();
        mProductsList = new ArrayList<Product>();
        try{


            ParseQuery<ParseObject> query = ParseQuery.getQuery("Products");
            query.orderByDescending("createdAt");
            query.whereEqualTo("user", userid);
            query.setCachePolicy(ParseQuery.CachePolicy.NETWORK_ELSE_CACHE);
            ob = query.find();
            for (ParseObject parseObject : ob) {               // Locate images in flag column

                String title = (String) parseObject.get("title");
                String descrip = (String) parseObject.get("descrip");
                preco = (String) parseObject.get("preco");
                String data = (String) parseObject.get("data");
                String detail = (String) parseObject.get("detail");
                user = (String) parseObject.get("user");
                imagefile = parseObject.getParseFile("foto");
                if (imagefile!=null){
                    imageUrl = parseObject.getParseFile("foto").getUrl();
                }
                productId = parseObject.getObjectId();

                product = new Product(title, descrip, preco, data, detail, user, imagefile, imageUrl, productId);



                mProductsList.add(product);
            }

        } catch (ParseException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
    return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // Locate the listview in listview_main.xml
        mListView.setAdapter(new MyAdapter());
        loadpd = (ProgressBar) getView().findViewById(R.id.loadpduser);
        getView();
        loadpd.setVisibility(View.INVISIBLE);



    }
}

Here's the fragment that holds those fragments in a view pager

public class MainActivity extends Fragment {
ViewPager viewPager;



@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.activity_main, null);

    viewPager = (ViewPager) view.findViewById(R.id.pager);
    viewPager.setAdapter(new MyPageAdapter(getChildFragmentManager()));

    ((MaterialNavigationDrawer)this.getActivity()).getToolbar().setLogo(R.drawable.bhlogo);
    ((MaterialNavigationDrawer)this.getActivity()).getToolbar().setTitle("");
    ((MaterialNavigationDrawer) this.getActivity()).setSupportActionBar(((MaterialNavigationDrawer) this.getActivity()).getToolbar());
    ((MaterialNavigationDrawer) this.getActivity()).getSupportActionBar();

    setHasOptionsMenu(true);





    return view;
}





@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_main, menu);
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.refresh:
            Intent intent = getActivity().getIntent();
            getActivity().finish();
            startActivity(intent);

            return false;

    }

    return false;
}


public class MyPageAdapter extends FragmentPagerAdapter{


    public MyPageAdapter(FragmentManager fm) {
        super(fm);
    }




    @Override
    public Fragment getItem(int position) {
        if (position == 0) {
            return new NewsFragment();
        }
        else {
            return new UserProductsFragment();
        }



    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if (position == 0) {
            return "Todos os anúncios";
        }
        else {
            return "Meus anúncios";
        }
    }



}
  • Add ` android:configChanges="orientation|screenSize"` with your `FragmentActivity` tag in your `Manifest.xml` – Anshul Tyagi May 20 '15 at 11:49
  • 1
    you can use headless fragments for this, just google "headless fragment to retain instance" and you will find examples for implementing it – Satyen Udeshi May 20 '15 at 11:56
  • Oh my goodness, the "android:configChanges="orientation|screenSize" did the trick, but how come? I've tried "android:configChanges="orientation|keyboardHidden" and it didn't work as expected... Anyway, thank you very much :) – Ricardo Soares May 20 '15 at 12:14

1 Answers1

1

Solution suggested by Anshul Tyagi

"Add android:configChanges="orientation|screenSize" with your FragmentActivity tag in your Manifest.xml"

is only applicable if your layout file is same for portrait and landscape both, means using single layout only. If that is the case, then this is best solution. But, if not then try this, which basically is Headless Fragment as pointed by Satyen

Ankit Bansal
  • 1,801
  • 17
  • 34