Работает и откладывается в Android 4.0 (библиотека GraphView для реального времени)

Я использую библиотеку GraphView для визуализации графиков в реальном времени. Пример библиотеки отлично работает на устройствах Android 2.X, однако он не работает должным образом на устройствах 4.X. График обновляется только тогда, когда я нажимаю на экран. Я новичок в Android, но я думаю, что проблема может заключаться в использовании runnable и postDelayed.

Это пример кода:

    package com.example.realtime;

import com.jjoe64.graphview.BarGraphView;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.GraphView.GraphViewData;
import com.jjoe64.graphview.GraphView.LegendAlign;
import com.jjoe64.graphview.GraphViewSeries;
import com.jjoe64.graphview.LineGraphView;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.LinearLayout;




public class RealTimeGraph extends Activity {
    private final Handler mHandler = new Handler();
    private Runnable mTimer1;
    private Runnable mTimer2;
    private GraphView graphView;
    private GraphViewSeries exampleSeries1;
    private GraphViewSeries exampleSeries2;
    private double graph2LastXValue = 5d;

private double getRandom() {
    double high = 3;
    double low = 0.5;
    return Math.random() * (high - low) + low;
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.graphs);

    // init example series data
    exampleSeries1 = new GraphViewSeries(new GraphViewData[] {
            new GraphViewData(1, 2.0d)
            , new GraphViewData(2, 1.5d)
            , new GraphViewData(2.5, 3.0d) // another frequency
            , new GraphViewData(3, 2.5d)
            , new GraphViewData(4, 1.0d)
            , new GraphViewData(5, 3.0d)
    });

    // graph with dynamically genereated horizontal and vertical labels
    if (getIntent().getStringExtra("type").equals("bar")) {
        graphView = new BarGraphView(
                this // context
                , "GraphViewDemo" // heading
        );
    } else {
        graphView = new LineGraphView(
                this // context
                , "GraphViewDemo" // heading
        );
    }
    graphView.addSeries(exampleSeries1); // data

    LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
    layout.addView(graphView);

    // ----------
    exampleSeries2 = new GraphViewSeries(new GraphViewData[] {
            new GraphViewData(1, 2.0d)
            , new GraphViewData(2, 1.5d)
            , new GraphViewData(2.5, 3.0d) // another frequency
            , new GraphViewData(3, 2.5d)
            , new GraphViewData(4, 1.0d)
            , new GraphViewData(5, 3.0d)
    });

    // graph with custom labels and drawBackground
    if (getIntent().getStringExtra("type").equals("bar")) {
        graphView = new BarGraphView(
                this
                , "GraphViewDemo"
        );
    } else {
        graphView = new LineGraphView(
                this
                , "GraphViewDemo"
        );
        ((LineGraphView) graphView).setDrawBackground(true);
    }
    graphView.addSeries(exampleSeries2); // data
    graphView.setViewPort(1, 4);
    graphView.setScalable(true);

    layout = (LinearLayout) findViewById(R.id.graph2);
    layout.addView(graphView);
}

@Override
protected void onPause() {
    mHandler.removeCallbacks(mTimer1);
    mHandler.removeCallbacks(mTimer2);
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    mTimer1 = new Runnable() {
        @Override
        public void run() {
            exampleSeries1.resetData(new GraphViewData[] {
                    new GraphViewData(1, getRandom())
                    , new GraphViewData(2, getRandom())
                    , new GraphViewData(2.5, getRandom()) // another frequency
                    , new GraphViewData(3, getRandom())
                    , new GraphViewData(4, getRandom())
                    , new GraphViewData(5, getRandom())
            });
            mHandler.postDelayed(this, 300);
        }
    };
    mHandler.postDelayed(mTimer1, 300);

    mTimer2 = new Runnable() {
        @Override
        public void run() {
            graph2LastXValue += 1d;
            exampleSeries2.appendData(new GraphViewData(graph2LastXValue, getRandom()), true);
            mHandler.postDelayed(this, 1000);
        }
    };
    mHandler.postDelayed(mTimer2, 1000);
}

}`

Важный код находится внутри функции OnResume.

Я действительно ценю любую подсказку...

Заранее спасибо!


person Rafag    schedule 13.05.2013    source источник


Ответы (1)


Я не понимаю, почему вы дважды вызываете обработчик posdelayed on - один раз внутри runnable и один раз после определения runnable...

Однако попробуйте аннулировать () представление после его обновления. Я бы сделал так:

@Override
protected void onResume() {
    super.onResume();
    mTimer1 = new Runnable() {
        @Override
        public void run() {
            exampleSeries1.resetData(new GraphViewData[] {
                    new GraphViewData(1, getRandom())
                    , new GraphViewData(2, getRandom())
                    , new GraphViewData(2.5, getRandom()) // another frequency
                    , new GraphViewData(3, getRandom())
                    , new GraphViewData(4, getRandom())
                    , new GraphViewData(5, getRandom())
            });
            exampleSeries1.invalidate();
        }
    };
    mHandler.postDelayed(mTimer1, 300);

    mTimer2 = new Runnable() {
        @Override
        public void run() {
            graph2LastXValue += 1d;
            exampleSeries2.appendData(new GraphViewData(graph2LastXValue, getRandom()), true);
            exampleSeries2.invalidate();
        }
    };
    mHandler.postDelayed(mTimer2, 1000);
}

Дайте мне знать, если это работает для вас

person Dan Riza    schedule 13.05.2013
comment
Причина вызова postDelayed() из метода run() заключается в том, что runnable будет рекурсивным и будет повторяться с задержкой 300 мс... удаление вызова postDelayed из метода run означает, что этот runnable сработает только один раз. - person FoamyGuy; 14.05.2013
comment
Вот именно, причина! Есть идеи? - person Rafag; 14.05.2013