Уничтожить фрагмент с помощью обработчика диаграммы в Activty onBackPressed - PullRequest
0 голосов
/ 01 мая 2018

У меня сейчас есть активность, которая содержит viewpager с fragments. Внутри этих fragments находятся графики, которые получают данные из URL. Чтобы добиться этого, я должен был добавить Handler, чтобы задержать процесс, чтобы приложение не зависало. Без этого данные не загружались достаточно быстро, поэтому я установил их на 3 секунды. Проблема, с которой я столкнулся, заключается в том, что когда я Backpress приложение вылетает, если диаграммы еще не загружены.

Я пытался реализовать метод override для onBackPressed в моем MainActivity, но это приводило к падению приложения каждый раз, когда я наносил ответный удар. Я также попытался использовать этот код из другого вопроса здесь, но он также не работал. Я действительно не уверен, как можно просто уничтожить Handler или Fragment, когда я вернусь из своей деятельности. Как я могу решить это?

Код, который я использовал, который не работал:

@Override
 public void onBackPressed() {

int count = getFragmentManager().getBackStackEntryCount();

if (count == 0) {
    super.onBackPressed();
    //additional code
} else {
    getFragmentManager().popBackStack();
}
}

MainActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_coin_detail);

    sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    viewPager = (ViewPager) findViewById(R.id.graph_container);
    setupViewPager(viewPager);
    viewPager.setOffscreenPageLimit(10);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.getTabAt(0).setText("1 Day");
    tabLayout.getTabAt(1).setText("7 Days");
    tabLayout.getTabAt(2).setText("30 Days");

    TextView header = findViewById(R.id.newtextViewHead);


    coinIMG = (ImageView) findViewById(R.id.imageView2);
    button_alert = (CircleButton) findViewById(R.id.button);
    button_fav = (CircleButton) findViewById(R.id.button_favorite);

    //Calls for intent
    Intent intent = getIntent();


//Tabs for fragment
private void setupViewPager(ViewPager viewPager){
    SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new Fragment_Graph1());
    adapter.addFragment(new Fragment_Graph2());
    adapter.addFragment(new Fragment_Graph3());
    viewPager.setAdapter(adapter);
}

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

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

    mChart = (LineChart) view.findViewById(R.id.chart1);
    mChart.setNoDataText("Getting Data From Server");
    mChart.setNoDataTextColor(Color.BLACK);
    makeChart();

    return view;
}

    private void makeChart() {

    StringRequest req = new StringRequest(Request.Method.GET, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {

                    Log.d(TAG, response.toString());

                    try {
                        jsonResponse = "";
                        JSONObject jObject = new JSONObject(response);
                        JSONArray jsonArray = jObject.getJSONArray("Data");
                        for (int i = 0; i <= jsonArray.length(); i++) {

                            JSONObject o = jsonArray.getJSONObject(i);

                            time = o.getString("time");
                            open = o.getString("close");

                            float val = Float.parseFloat(open);

                            yVals1.add(new Entry(i, val));

                            long unixSeconds = Long.parseLong(time);
                            Date date = new Date(unixSeconds * 1000L);
                            SimpleDateFormat sdf = new SimpleDateFormat("HH:MM");
                            sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
                            String formattedDate = sdf.format(date);

                            xValues.add(formattedDate);

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

            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d(TAG, "Error: " + error.getMessage());
        }
    });

    Graph_AppController.getInstance().addToRequestQueue(req);

    handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {

            mChart.setBackgroundColor(Color.WHITE);
            mChart.setGridBackgroundColor(Color.WHITE);
            mChart.setDrawGridBackground(true);
            mChart.setDrawBorders(true);

            Legend l = mChart.getLegend();
            l.setEnabled(false);

            XAxis xAxis = mChart.getXAxis();
            xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
            xAxis.setDrawGridLines(false);
            xAxis.setAxisLineColor(Color.BLACK);
            xAxis.setTextColor(Color.BLACK);

            xAxis.setValueFormatter(new DefaultAxisValueFormatter(0) {
                @Override
                public String getFormattedValue(float value, AxisBase axis) {
                    return xValues.get((int) value % xValues.size());
                }

                @Override
                public int getDecimalDigits() {
                    return 0;
                }
            });

            YAxis leftAxis = mChart.getAxisLeft();
            leftAxis.setTextColor(Color.BLACK);
            leftAxis.setDrawAxisLine(true);
            leftAxis.setDrawZeroLine(false);
            leftAxis.setDrawGridLines(false);
            leftAxis.setGridColor(Color.WHITE);
            leftAxis.setAxisLineColor(Color.BLACK);

            mChart.getAxisRight().setEnabled(false);
            LineDataSet set1;


            set1 = new LineDataSet(yVals1, "DataSet 1");

            set1.setAxisDependency(YAxis.AxisDependency.LEFT);
            set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
            set1.setColor(Color.parseColor("#008000"));
            set1.setDrawCircles(true);
            set1.setLineWidth(3f);
            set1.setCircleRadius(1f);
            set1.setCircleColor(Color.parseColor("#008000"));
            set1.setFillAlpha(50);
            set1.setDrawFilled(true);
            set1.setFillColor(Color.parseColor("#008000"));
            set1.setHighLightColor(Color.rgb(244, 117, 117));
            set1.setDrawCircleHole(false);

            dataSets.add(set1);

            LineData datab = new LineData(dataSets);
            datab.setDrawValues(false);

            mChart.setData(datab);
            mChart.setDrawMarkers(true);
            IMarker marker = new YourMarkerView(getContext(),R.layout.custom_marker);
            mChart.setMarker(marker);

        }
    }, 3000);
}
public class YourMarkerView extends MarkerView {

    private TextView tvContent;

    public YourMarkerView(Context context, int layoutResource) {
        super(context, layoutResource);

        // find your layout components
        tvContent = (TextView) findViewById(R.id.tvContent);
    }

    // callbacks everytime the MarkerView is redrawn, can be used to update the
    // content (user-interface)
    @Override
    public void refreshContent(Entry e, Highlight highlight) {

        tvContent.setText("$" + e.getY());

        // this will perform necessary layouting
        super.refreshContent(e, highlight);
    }

    private MPPointF mOffset;

    @Override
    public MPPointF getOffset() {

        if(mOffset == null) {
            // center the marker horizontally and vertically
            mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
        }

        return mOffset;
    }


    @Override
    public void draw(Canvas canvas, float posX, float posY) {
        posX = 400;
        posY = -30;

        canvas.translate(posX,posY);
        draw(canvas);
        canvas.translate(-posX,-posY);

    }
}

1 Ответ

0 голосов
/ 01 мая 2018

Проблема в том, что у вас утечка памяти с вашим фрагментом. Сетевой запрос вернется к фрагменту, который больше не существует. Ваш обработчик запустит поток и попытается получить доступ к элементам, которые были уничтожены. Вы не должны использовать обработчик с фиксированным периодом времени, что если ваш запрос займет более 3 секунд, чтобы вернуться? Вам нужно заполнять данные диаграммы только тогда, когда вы получите результат, измените метод makechart на этот:

private void makeChart() {

    StringRequest req = new StringRequest(Request.Method.GET, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {

                    Log.d(TAG, response.toString());

                    try {
                        jsonResponse = "";
                        JSONObject jObject = new JSONObject(response);
                        JSONArray jsonArray = jObject.getJSONArray("Data");
                        for (int i = 0; i <= jsonArray.length(); i++) {

                            JSONObject o = jsonArray.getJSONObject(i);

                            time = o.getString("time");
                            open = o.getString("close");

                            float val = Float.parseFloat(open);

                            yVals1.add(new Entry(i, val));

                            long unixSeconds = Long.parseLong(time);
                            Date date = new Date(unixSeconds * 1000L);
                            SimpleDateFormat sdf = new SimpleDateFormat("HH:MM");
                            sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
                            String formattedDate = sdf.format(date);

                            xValues.add(formattedDate);

                        }
                    //finished receiving data
                    fillChartData();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d(TAG, "Error: " + error.getMessage());
        }
    });

    Graph_AppController.getInstance().addToRequestQueue(req); 
}

Создайте новый метод с именем fillChartData, переместите весь код вашего обработчика в этот метод и вызовите его, когда вы закончите получать данные. Таким образом, вам не нужно использовать обработчик.

public void fillChartData(){
  mChart.setBackgroundColor(Color.WHITE);
                mChart.setGridBackgroundColor(Color.WHITE);
                mChart.setDrawGridBackground(true);
                mChart.setDrawBorders(true);

                Legend l = mChart.getLegend();
                l.setEnabled(false);

                XAxis xAxis = mChart.getXAxis();
                xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
                xAxis.setDrawGridLines(false);
                xAxis.setAxisLineColor(Color.BLACK);
                xAxis.setTextColor(Color.BLACK);

                xAxis.setValueFormatter(new DefaultAxisValueFormatter(0) {
                    @Override
                    public String getFormattedValue(float value, AxisBase axis) {
                        return xValues.get((int) value % xValues.size());
                    }

                    @Override
                    public int getDecimalDigits() {
                        return 0;
                    }
                });

                YAxis leftAxis = mChart.getAxisLeft();
                leftAxis.setTextColor(Color.BLACK);
                leftAxis.setDrawAxisLine(true);
                leftAxis.setDrawZeroLine(false);
                leftAxis.setDrawGridLines(false);
                leftAxis.setGridColor(Color.WHITE);
                leftAxis.setAxisLineColor(Color.BLACK);

                mChart.getAxisRight().setEnabled(false);
                LineDataSet set1;


                set1 = new LineDataSet(yVals1, "DataSet 1");

                set1.setAxisDependency(YAxis.AxisDependency.LEFT);
                set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
                set1.setColor(Color.parseColor("#008000"));
                set1.setDrawCircles(true);
                set1.setLineWidth(3f);
                set1.setCircleRadius(1f);
                set1.setCircleColor(Color.parseColor("#008000"));
                set1.setFillAlpha(50);
                set1.setDrawFilled(true);
                set1.setFillColor(Color.parseColor("#008000"));
                set1.setHighLightColor(Color.rgb(244, 117, 117));
                set1.setDrawCircleHole(false);

                dataSets.add(set1);

                LineData datab = new LineData(dataSets);
                datab.setDrawValues(false);

                mChart.setData(datab);
                mChart.setDrawMarkers(true);
                IMarker marker = new YourMarkerView(getContext(),R.layout.custom_marker);
                mChart.setMarker(marker);
}
...