Android Studio - 按下按钮启动和停止循环

时间:2017-10-09 00:55:26

标签: java android loops

我刚才使用Android Studio,目前正在编写一款应用程序,该应用程序利用手机中的传感器来控制其他设备。我搜索过并找不到太多可以帮助我解决问题的方法。最终,我需要通过网络传输从传感器获得的数据,但我还没有接近那一点,以至于还有一天。

目前,该应用可以访问传感器并在手机屏幕上显示。每次按下屏幕按钮,它都会更新读数。我想要它做的是,一旦我按下按钮一次,在手机移动时不断地实时更新值。如果再次按下该按钮,我希望它停止。以下是我在主要活动中的当前代码。我试图做的是使用一个整数,我会在每次按下按钮时切换,并在其中一个值上运行do while循环。当do while循环在那里时它不会做任何事情。如果我把它拿出来,就会像每次按下按钮时更新值一样运行。我也正在展示"切换"的价值。在传感器值旁边,当do while循环不在那里时切换。我不明白为什么while循环根本不会运行。我也尝试使用布尔值并在true和false之间切换,但我得到了相同的结果。我也意识到do while循环的设置方式可能无法停止,但我认为它至少会进入循环并继续运行。至少让我开始了。

    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.app.Activity;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.widget.TextView;
    import android.widget.Button;
    import android.view.View;





    public class MainActivity extends AppCompatActivity
    {
MySensorUpdateThread mySensorUpdateThread = null;

@Override

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mySensorUpdateThread = new MySensorUpdateThread(this);

    SensorManager sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);

    final float[] mValuesMagnet = new float[3];
    final float[] mValuesAccel = new float[3];
    final float[] mValuesOrientation = new float[3];
    final float[] mRotationMatrix = new float[9];

    final Button btn_valider = (Button) findViewById(R.id.btn1);
    final TextView txt1 = (TextView) findViewById(R.id.textView1);
    final SensorEventListener mEventListener = new SensorEventListener() {
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }

        public void onSensorChanged(SensorEvent event) {
            switch (event.sensor.getType()) {
                case Sensor.TYPE_ACCELEROMETER:
                    System.arraycopy(event.values, 0, mValuesAccel, 0, 3);
                    break;

                case Sensor.TYPE_MAGNETIC_FIELD:
                    System.arraycopy(event.values, 0, mValuesMagnet, 0, 3);
                    break;
            }
        }
        ;
    };

    setListners(sensorManager, mEventListener);

    btn_valider.setOnClickListener(new View.OnClickListener()
        {

        public void onClick(View view)
        {
            mySensorUpdateThread.toggleThread();
            if (mySensorUpdateThread.isRunning())
            {
                mySensorUpdateThread.start();
            }
        }

        });
}

public void setListners(SensorManager sensorManager, SensorEventListener mEventListener)
{
    sensorManager.registerListener(mEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_NORMAL);
    sensorManager.registerListener(mEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
            SensorManager.SENSOR_DELAY_NORMAL);
}

public class MySensorUpdateThread extends Thread
{
    private boolean keepRunning = false;
    private String sensorResults = "";


    private MainActivity mActivity;

    public MySensorUpdateThread(MainActivity activity)
    {
        this.mActivity = activity;
    }
    public void toggleThread()
    {
        this.keepRunning = !this.keepRunning;
    }

    public boolean isRunning()
    {
        return this.keepRunning;
    }

    public String getSensorResults()
    {
        return this.sensorResults;
    }

    @Override
    public void run()
    {

        int i = 0;
        int maxIterations = 100;
        try{
            while(this.keepRunning)
            {
                // This keeps the thread from going on too long in case
                if(i > maxIterations)
                {
                    this.keepRunning = false;
                    break;
                }

                // This causes the thread to rest for 50ms to
                // slow things down

                try
                {
                    Thread.sleep(50);
                }
                catch(InterruptedException e)
                {
                }
                SensorManager.getRotationMatrix(mRotationMatrix, null, mValuesAccel, mValuesMagnet);
                SensorManager.getOrientation(mRotationMatrix, mValuesOrientation);

                sensorResults = "Roll/Pitch (degrees): " + /*mValuesOrientation[0]*(180/Math.PI) + " "+ "," + " " +*/
                        mValuesOrientation[1] * (180 / Math.PI) + " " + "/" + " " +
                        mValuesOrientation[2] * (-180 / Math.PI);

                // Now post the results to the UI Thread
                runOnUiThread(new Runnable(){
                    @Override
                    public void run(){
                        txt1.setText(getSensorResults());
                    }
                });
            }
        }
        catch()
        {
            Log.e(TAG, ex.getMessage());
        }
    }
}

}

2 个答案:

答案 0 :(得分:0)

将传感器读数放在后台线程中。这只是一个例子。根据需要进行修改!

Activity课程中,您需要设置后台线程对象:

MySensorUpdateThread mySensorUpdateThread = null;

在您的活动onCreate()方法中,通过添加:

来初始化后台线程
mySensorUpdateThread = new MySensorUpdateThread();

onClick()方法中启动并停止后台线程:

public void onClick(View view){
    mySensorUpdateThread.toggleThread();
    if(mySensorUpdateThread.isRunning()){
        mySensorUpdateThread.start();
    }
});

现在这里是后台线程的代码:

public class MySensorUpdateThread extends Thread{
    SensorManager sensorManager = null;
    private boolean keepRunning = false;
    private String sensorResults = "";

    public void toggleThread(){
        this.keepRunning = !this.keepRunning;
    }

    public void isRunning(){
        return this.keepRunning;
    }

    public String getSensorResults(){
        return this.sensorResults;
    }

    @Override
    public void run(){
        if(sensorManager == null){
            sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
        }

        int i = 0;
        int maxIterations = 100;
        String mess = "";
        try{
            while(this.keepRunning){
                mess = "Number of iterations:  " + i;
                Log.e(TAG, mess);
                // This keeps the thread from going on too long in case 
                if(i > maxIterations){
                    this.keepRunning = false;
                    break;
                }

                // This causes your thread to rest for 500ms it might be a 
                // good idea to slow things down a bit -- just a suggestion
                Thread.sleep(500);


                // Get your sensor data here and set it to the 
                // local variable to be posted to the UI Thread
                //this.sensorResults = sensorString;


                // Now post the results to the UI Thread
                runOnUiThread(new Runnable(){
                    @Override
                    public void run(){
                         txt1.setText(getSensorResults());
                    }
                }

            }
        }
        catch(){
            Log.e(TAG, ex.getMessage());
        }
    }

}

您可能希望停止活动onPause()方法的后台主题,并可能在onResume()上重新启动它。

答案 1 :(得分:0)

当我使用处理程序线程进行长时间任务时,我发现它很有用,处理程序线程是机器人处理长时间运行任务的官方方式。这是官方链接 有关如何使用处理程序线程的更多信息。

https://developer.android.com/reference/android/os/HandlerThread.html