Вопрос

My main Thread extends from Activity, it starts two asynchronous tasks that gather data from different UDP sources. One of this tasks should append the data to this graph drawing library. I am making updates on the UI from the onPostExecute section of AsynTask:

@Override
protected void onPostExecute(Integer result) {
    super.onPostExecute(result);
    edt2.setText(Integer.toString(result));
    // Graph Update
    if (graphActive) {
        exampleSeries1.appendData(ATList.get(ATList.size()-1), true);
    } else {
        //do nothing
    }
}

The data is passed to the graph and if I click with my finger on the display it is displayed correctly, but I want the software to update the graph automatically. The edt2 textfield is updated automatically.

I tried the following:

layout.postInvalidate(); //and invalidate

I have no idea how to make Android to update the GraphView.

This is the respective part of the XML:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/graph1"
    android:layout_width="match_parent"
    android:layout_height="305dp" >

</LinearLayout>

Thank you very much for your help!

Это было полезно?

Решение

AsyncTask is not a Ui Thread use runOnUiThread(..) instead Asynctask.

1 rl-: parent view. 2 myView -: Child View

//Use This Method //

    runOnUiThread(new Runnable() {

        //@Override
        public void run() {
            // TODO Auto-generated method stub
            rl.addView(new myView(getApplicationContext()));
        }
    });

Другие советы

The answer by @Rishabh is not correct. Both onPostExecture and onProgressUpdate are called on the UI thread. The accepted solution is more kludgy than the original track you were on, that is to update in onPostExecute. Doing it there is absolutely the elegant way to do. You do NOT want to call runOnUiThread here.

As @weakwire said: invalidating the graph is the right way, not invalidating the layout. Anyways, the accepted answer is not the Android way to perform a task in the background and then update the UI with the results.

For changes to take effect, you need to call:

graphView.onDataChanged(false, false);

This will invalidate the GraphView and the GridLabelRenderer as @weakwire and @vkinra suggest, but this is the recommended way to go, as you can see in GridLabelRenderer#invalidate(boolean, boolean)'s javadoc:

/**
 * Clears the internal cache and forces to redraw the grid and labels.
 *
 * Normally you should always call {@link GraphView#onDataChanged(boolean, boolean)}
 * which will call this method.
 *
 * @param keepLabelsSize true if you don't want to recalculate the size of the labels. 
 *                       It is recommended to use "true" because this will improve 
 *                       performance and prevent a flickering.
 * @param keepViewport true if you don't want that the viewport will be recalculated.
 *                     It is recommended to use "true" for performance.
 */
public void invalidate(boolean keepLabelsSize, boolean keepViewport) { /*...*/ }

And these are the same parameters of GraphView#onDataChanged(boolean, boolean), so you should play with them to ensure the best performance. Also, you can take a look at this answer to see the GraphView#onDataChanged(boolean, boolean)'s javadoc.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top