0

I would like to make method onSenzorChange run into thread. To run more smooth. And get information of x axis everytime change. And pass it to main class (Activity) into TextView.

MainActivity class :

public class MainActivity extends AppCompatActivity {
    TextView textView;
    TestOfPassUIThread t;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);

        t = new TestOfPassUIThread(this);
    }
    public void onStart(View view) {
        t.register();
    }
}

TestOfPassUIThread class ( not an activity or anything )

public class TestOfPassUIThread implements SensorEventListener {

    private SensorManager sensorManager;
    private Sensor sensor;

    public TestOfPassUIThread (Context context) {
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }
    public void register(){
        sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
    }
    public void unregister() {
        sensorManager.unregisterListener(this);
    }
    // Want this method be in Thread
    //How can I do this ?
    @Override
    public void onSensorChanged(SensorEvent event) {
        float xAxis = event.values[0];
        // And I want it to display in TextView!
        // In main activity would be textView.setText("" + xAxis);
        //How to pass it to MainActivity class ?
    }
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}
josedlujan
  • 5,357
  • 2
  • 27
  • 49
Mjafko
  • 151
  • 1
  • 2
  • 13

1 Answers1

1

There are multiple ways to achieve writing on the textview, the following is one way to do it. (you may wanna read about callbacks, check How to implement callbacks in Java).

As for accessing the UI thread from the background, there multiple ways to do it as well (check: Running code in main thread from another thread).

For why we used a HandlerThread below, you can read about it here: Acclerometer Sensor in Separate Thread.

So your listener becomes:

public abstract class TestOfPassUIThread implements SensorEventListener {

    private SensorManager   sensorManager;
    private Sensor          sensor;
    private HandlerThread   handlerThread;
    private Context         context;
    private Runnable        uiRunnable;

    private float           xAxis;

    public TestOfPassUIThread (Context context) {
        this.context    = context;
        sensorManager   = (SensorManager) context.getSystemService (Context.SENSOR_SERVICE);
        sensor          = sensorManager.getDefaultSensor (Sensor.TYPE_ACCELEROMETER);
    }

    public void register () {
        initUiRunnable ();

        handlerThread   = new HandlerThread ("sensorHandler");
        handlerThread.start ();

        sensorManager.registerListener (
            this,
            sensor,
            SensorManager.SENSOR_DELAY_NORMAL,
            new Handler (handlerThread.getLooper ())
        );
    }

    public void unregister () {
        sensorManager.unregisterListener (this);

        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                handlerThread.quitSafely ();
                return;
            }
            handlerThread.quit ();
        } finally {
            uiRunnable = null;
        }
    }

    @Override
    public void onSensorChanged (SensorEvent event) {
        xAxis = event.values [0];

        // your other background operations

        ((Activity)context).runOnUiThread (uiRunnable);

        // your other background operations
    }

    @Override
    public void onAccuracyChanged (Sensor sensor, int accuracy) {

    }

    private void initUiRunnable () {
        uiRunnable = new Runnable () {

            @Override
            public void run () {
                // ...... your other UI operations

                fillTextView (xAxis);

                // ...... your other UI operations
            }
        };
    }

    public abstract void fillTextView (float xAxis);
}

And your activity:

public class MainActivity extends AppCompatActivity {

    private TextView           textView;
    private TestOfPassUIThread t;

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

        textView = (TextView)findViewById (R.id.textView);

        t = new TestOfPassUIThread (this) {

            @Override
            public void fillTextView (float xAxis) {
                textView.setText ("Current xAxis: " + xAxis);
            }
        };
    }

    @Override
    protected void onResume () {
        super.onResume ();
        t.register ();
    }

    @Override
    protected void onPause () {
        t.unregister ();
        super.onPause ();
    }
}

Also, when you override LifeCycle methods of Activities such as onStart, onResume etc..., make sure to call the super.lifeCycleMethod.


Community
  • 1
  • 1
  • Thank you for this. Got one question about " Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 ". Is there anything that is only in API higher of Jelly Bean ? Or could I do here ICE_CREAM_SANDWICH_MR1 ? – Mjafko Jan 29 '17 at 18:18
  • And " sensorManager.registerListener (this, sensor, SensorManager.SENSOR_DELAY_NORMAL,new Handler(handlerThread.getLooper ()) ); " in this line new Handler cosing me error ( crash ). – Mjafko Jan 29 '17 at 18:37
  • @Mjafko, question1: the condition that I wrote is handling the version you say... question2: what's the exception? –  Jan 29 '17 at 21:20
  • @Mjafko, check my edit, I forgot to start the `handlerThread.start ()` on the `register ()` method, which was causing an NullPointerException. (I just tested it, it works now ;)) –  Jan 30 '17 at 00:21
  • @Mjafko, I also fixed your activity callbacks missing `super.onStart`.. If my answer helped you don't hesitate to upvote and mark the answer as accepted :) –  Jan 30 '17 at 00:33
  • One more question if I may. Got problem to pause it and start it again after. Got "Only one Looper may be created per thread" am I missing something ? – Mjafko Jan 30 '17 at 10:05
  • @Mjafko, give me some time, I'll run this code and fix it –  Jan 30 '17 at 10:53
  • Thank your so much. I am kinda new at this. Trying to understand and figure it out :) – Mjafko Jan 30 '17 at 10:57