FragmentStatePagerAdapter + AsyncTask + ProgressDialog

Activity Lifecycle, Saving Activity State, Managing Tasks, Intent, Intent Filter
Ответить
patalaka
Сообщения: 15
Зарегистрирован: 26 мар 2012, 19:38

FragmentStatePagerAdapter + AsyncTask + ProgressDialog

Сообщение patalaka » 01 авг 2015, 03:46

Всем привет. В моем приложении я использую FragmentStatePagerAdapter, который создает фрагмент. Сам фрагмент вызывает AsyncTask, обрабатывает GET запрос, и возвращает JSON строку. Все это разбирает самописный метод и отдает ArrayList, который я разбираю и вывожу на экран.
Приложение не крашится, работает. Но когда я перелистываю фрагменты, ProgressDialog не срабатывает вовремя. А если плохое соединение, то перелистывает с тормозами и ProgressDialog не выскакивает.

Подскажите пожалуйста, как мне решить эту проблему?

Код фрагмента:

Код: Выделить всё

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import m.i.horoscopus.R;
import m.i.horoscopus.model.OneHoroscope;


public class BottomFragment extends Fragment {
    public static final String PAGE_ARGS = "page_id";
    public static final String LINK_ZODIAC = "zodiacLink";
    private TextView mTitleContent, mTextContent;
    private LinearLayout mLinLayout;
    private ScrollView mScrollView;


    List<OneHoroscope> allHoroscopes;
    AsyncTask myTask;
    private String task;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Bundle bundle = getArguments();

        //Создание AsyncTask и передача параметров в конструктор
        myTask = new MyPageDownloader(bundle.getInt(PAGE_ARGS), bundle.getString(LINK_ZODIAC), getActivity()).execute();

        //Получение строки JSON
        try {
            task = (String) myTask.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        //Разбор и сортировка в ArrayList
        parseJsonText(task);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mScrollView = new ScrollView(getActivity());
        mScrollView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        mLinLayout = new LinearLayout(getActivity());
        mLinLayout.setOrientation(LinearLayout.VERTICAL);
        mLinLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));


        for(OneHoroscope h:allHoroscopes){
            View view = inflater.inflate(R.layout.item_content_fragment, container, false);
            mTitleContent = (TextView) view.findViewById(R.id.title_content);
            mTitleContent.setText(h.getTitle());
            mTextContent = (TextView) view.findViewById(R.id.text_content);
            mTextContent.setText(h.getText());

            mLinLayout.addView(view);
        }
        mScrollView.addView(mLinLayout);

        return mScrollView;
    }




    private void parseJsonText(String strJson){
        try {
            JSONObject dataJson = new JSONObject(strJson);
            JSONArray horoscopes = dataJson.getJSONArray("horoscope");
            JSONObject horoscope = horoscopes.getJSONObject(0);

            allHoroscopes = new ArrayList<>();
            allHoroscopes.add(new OneHoroscope("11.12.2015", "com", R.string.com, horoscope.getString("com")));
            allHoroscopes.add(new OneHoroscope("11.12.2015", "ero", R.string.ero, horoscope.getString("ero")));
            allHoroscopes.add(new OneHoroscope("11.12.2015", "anti", R.string.anti, horoscope.getString("anti")));
            allHoroscopes.add(new OneHoroscope("11.12.2015", "bus", R.string.bus, horoscope.getString("bus")));
            allHoroscopes.add(new OneHoroscope("11.12.2015", "hea", R.string.hea, horoscope.getString("hea")));
            allHoroscopes.add(new OneHoroscope("11.12.2015", "cook", R.string.cook, horoscope.getString("cook")));
            allHoroscopes.add(new OneHoroscope("11.12.2015", "lov", R.string.lov, horoscope.getString("lov")));
            allHoroscopes.add(new OneHoroscope("11.12.2015", "mob", R.string.mob, horoscope.getString("mob")));

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


    /**
     * This is downloader pages.
     */
    public class MyPageDownloader extends AsyncTask<Void,Void,String> {
        HttpURLConnection urlConnection;
        BufferedReader reader;
        private String mZodiac, resultJson;
        private int mIdDay;

        Context context;
        ProgressDialog pd;

        public MyPageDownloader(int mIdDay, String mZodiac, Context context){
            this.mIdDay = mIdDay;
            this.mZodiac = mZodiac;
            this.context = context;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pd = new ProgressDialog(context);
            pd.setMessage(context.getResources().getString(R.string.loading));
            pd.setCancelable(true);
            pd.show();
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if(pd != null) {
                pd.dismiss();
            }
        }

        @Override
        protected String doInBackground(Void... params) {
            try {
                URL url = new URL("http://myapps.com.ua/horoscopus/get_one_horoscope.php?zodiac="+ mZodiac +"&id=" + String.valueOf(mIdDay));

                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();

                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();

                reader = new BufferedReader(new InputStreamReader(inputStream));

                String line;
                while((line = reader.readLine()) != null){
                    buffer.append(line);
                }

                resultJson = buffer.toString();

            } catch (Exception e) {
                e.printStackTrace();
            }
            return resultJson;
        }
    }

}

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: FragmentStatePagerAdapter + AsyncTask + ProgressDialog

Сообщение Mykola » 03 авг 2015, 15:31

Привет,
Почитай про жизненный цикл фрагмента.

Ты используешь FragmentStatePagerAdapter - посмотри в дебаге на метод onAttach.
Почему используешь FragmentStatePagerAdapter?

Прочитай про потоки, allHoroscopes не боишся что колекция может быть не заполнена на момент вызова onCreateView.
Может нужно использовать ListView;

А reader кто будет закрывать, я понимаю что есть GB.
Прочитай про memory leak.

patalaka
Сообщения: 15
Зарегистрирован: 26 мар 2012, 19:38

Re: FragmentStatePagerAdapter + AsyncTask + ProgressDialog

Сообщение patalaka » 04 авг 2015, 11:17

Mykola писал(а):Привет,
Почитай про жизненный цикл фрагмента.

Ты используешь FragmentStatePagerAdapter - посмотри в дебаге на метод onAttach.
Почему используешь FragmentStatePagerAdapter?

Прочитай про потоки, allHoroscopes не боишся что колекция может быть не заполнена на момент вызова onCreateView.
Может нужно использовать ListView;

А reader кто будет закрывать, я понимаю что есть GB.
Прочитай про memory leak.
Про потоки и ридер Вы правы. Спасибо.
Но я думаю что моя работа в корне не верна. Не стоит запускать AsynkTask внутри FragmentStatePagerAdapter - так как вызывается 3 асинка сразу. Стоит сначала получать информацию а потом передавать ее в FragmentStatePagerAdapter.

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: FragmentStatePagerAdapter + AsyncTask + ProgressDialog

Сообщение Mykola » 11 авг 2015, 13:23

Стоит показывать прогресс на фрагменте и после окончания показывать данные.

Ответить