Java 从连接到Android的传感器连续采集数据(线程、异步任务、服务)

Java 从连接到Android的传感器连续采集数据(线程、异步任务、服务),java,android,multithreading,Java,Android,Multithreading,我已将一个传感器连接到Android手机。传感器测量响应并在应用程序上显示相应结果。我试图使用Java定时器,但现在计划转到线程 在连续模式下,应用程序将完全禁用,不需要任何用户吸引。用户需要设置一些预采集设置,然后按下开始按钮。启动此按钮后,主GUI将持续更新,但在操作进行期间,用户无法与应用程序交互。用户需要再次按下“开始”按钮来停止应用程序。此时,启动按钮将充当停止按钮 我刚接触安卓系统,所以我在互联网上进行了研究,发现比起thread,Asyntask是更好的选择。然后有人还提到,服务也

我已将一个传感器连接到
Android手机
。传感器测量响应并在应用程序上显示相应结果。我试图使用
Java定时器
,但现在计划转到
线程

在连续模式下,应用程序将完全禁用,不需要任何用户吸引。用户需要设置一些预采集设置,然后按下开始按钮。启动此按钮后,
主GUI
将持续更新,但在操作进行期间,用户无法与应用程序交互。用户需要再次按下“开始”按钮来停止应用程序。此时,启动按钮将充当停止按钮

我刚接触安卓系统,所以我在互联网上进行了研究,发现比起
thread
Asyntask
是更好的选择。然后有人还提到,
服务
也可以更好地运行长进程或
并发
。我希望我的应用程序能够运行很长时间而不会停止或内存泄漏

你认为对我来说什么更好?同时,我尝试使用
AsyncTask

这是我使用
AsynTask
的代码。我希望此代码持续运行并更新UI线程<代码>用户界面有一个图形,该图形将使用后台数据进行更新

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

final Button button = (Button) findViewById(R.id.button1); //This button will start and stop the app.
button.setOnClickListener(addOnButtonClick(button));
}
//按下主按钮,然后从按钮信号调用AYSNTASK。我刚刚实现了
doInBackground
功能

 View.OnClickListener addOnButtonClick(final Button button){
        return  new View.OnClickListener()
        {
            public void onClick(View v)
            {
                new AsyncTaskActivity().doInBackground();
//Here i want to add one flag, which will be activated as 'true`when the
//button will be pressed once and `fasle` when the button will be pressed //second time. 
//True-> activity run, false ->activity stop.
                }
            };
        }

 public class AsyncTaskActivity extends AsyncTask<Void , Void, Void>{


        @Override
        protected Void doInBackground(Void... params){


                nativeData = getDatafromsensor(); //Data from native.

                DataPoint[] data = new DataPoint[Size];
                for (int i=0; i<Size; i++) {
                    double x = i;
                    double y = nativeData[i];
                    DataPoint v = new DataPoint(x, y);
                    data[i] = v;
                    }
                }
                series.resetData(data);
            }
return null;
        }
View.OnClickListener添加按钮单击(最终按钮){
返回新视图。OnClickListener()
{
公共void onClick(视图v)
{
新建AsyncTaskActivity().doInBackground();
//这里我想添加一个标志,当
//按钮将按下一次,第二次按下按钮时按下“fasle”。
//真->活动运行,假->活动停止。
}
};
}
公共类AsyncTaskActivity扩展了AsyncTask{
@凌驾
受保护的Void doInBackground(Void…参数){
nativeData=getDatafromsensor();//来自本机的数据。
数据点[]数据=新数据点[大小];

对于(int i=0;i我认为
服务
可能是一种长期的方法,但下面介绍如何使用
异步任务

您应该仔细阅读的“用法”部分,以便了解UI线程方法和后台线程方法之间的交互。在
onClick()
方法中,您直接调用
doInBackground()
,这是不允许的。您调用
execute()
doInBackground()因此,在不同的线程上调用了

AsyncTask
有一种更新进度的方法。它用于在后台线程仍在运行时更新(例如)进度条(必须从UI线程完成)。实际上,您可以使用它来实现您的目标

下面是一些示例代码:

创建
AsyncTask
的子类以运行数据捕获线程:

public class SensorTask extends AsyncTask<Void, List<Double>, Void> {

    protected void onPreExecute() {
        // runs on the UI thread
        // TODO set up your UI for data acquisition
    }

    protected Void doInBackground(Void... params) {

        // TODO initialize sensor for acquisition

        while (! isCancelled()) {

            nativeData = getDatafromsensor(); //Data from native.
            List<Double> sensorData = new ArrayList<Double>();

            for (int i = 0; i < nativeData.length; i++) {
                sensorData.add(new Double(nativeData[i]);
            }
            publishProgress(sensorData);  // this invokes onProgressUpdate on UI thread
            Thread.sleep(DELAY_TIME);  // if you need to
        }

        // TODO sensor cleanup
    }

    protected void onProgressUpdate(List<Double>... values) {
        // runs on the UI thread
        // TODO update your UI with the sensor data
    }

    protected void onCancelled(Void result) {
        // runs on the UI thread
        // TODO update UI for acquisition complete
    }

}
这一点很重要:确保在活动的
onPause()
方法中取消任务,以便线程仅在活动为当前活动时运行


编辑: 使用全局数组具有消除额外对象分配的优点。只需确保同步对数据数组的访问即可。 下面是使用全局数组编写
AsyncTask
的另一种方法:

public class SensorTask extends AsyncTask<Void, Void, Void> {

    protected void onPreExecute() {
        // runs on the UI thread
        // TODO set up your UI for data acquisition
    }

    protected Void doInBackground(Void... params) {

        // TODO initialize sensor for acquisition

        while (! isCancelled()) {

            synchronized (nativeData) {
                nativeData = getDatafromsensor(); // Data from native.
            }
            publishProgress(null);  // this invokes onProgressUpdate on UI thread
            Thread.sleep(DELAY_TIME);  // if you need to
        }

        // TODO sensor cleanup
    }

    protected void onProgressUpdate(Void... values) {
        // runs on the UI thread
        synchronized (nativeData) {
            // TODO update your UI with the sensor data
        }
    }

    protected void onCancelled(Void result) {
        // runs on the UI thread
        // TODO update UI for acquisition complete
    }

}
公共类SensorTask扩展了AsyncTask{
受保护的void onPreExecute(){
//在UI线程上运行
//TODO设置数据采集的用户界面
}
受保护的Void doInBackground(Void…参数){
//TODO初始化传感器以进行采集
而(!isCancelled()){
已同步(nativeData){
nativeData=getDatafromsensor();//来自本机的数据。
}
publishProgress(null);//这将在UI线程上调用onProgressUpdate
Thread.sleep(延迟时间);//如果需要
}
//TODO传感器清理
}
受保护的void onProgressUpdate(void…值){
//在UI线程上运行
已同步(nativeData){
//TODO使用传感器数据更新用户界面
}
}
取消后受保护的作废(作废结果){
//在UI线程上运行
//完成采集的TODO更新UI
}
}

我使用了您的技术,在
pre
中,我设置了图形索引并初始化了条件。在
后台
中,我调用了本机函数并从传感器获取了数据。在
发布
中,我以图形形式显示数据,为此我使用了
图形视图
库。这里密码是什么

public class AsyncTaskActivity extends AsyncTask<Void, Double, Void> {


    protected void onPreExecute() {
            viewport.setMinY(0);
            viewport.setMaxY(8000);
            viewport.setMinX(0);
            viewport.setMaxX(330);
            staticLabelsFormatter = new StaticLabelsFormatter(graph);
            staticLabelsFormatter.setHorizontalLabels(new String[]{"400", "500", "600", "730"});
            graph.getGridLabelRenderer().setLabelFormatter(staticLabelsFormatter);

        } 


    protected Void doInBackground(Void... params) {

        while (!isCancelled()) {
            synchronized (nativeData) {
            nativeData = getDatafromsensor(); // Data from native.
        }
        publishProgress(null);  // this invokes onProgressUpdate on UI thread
    }
    }

    protected void onProgressUpdate(Void... values) {

///This one here
            series.setBackgroundColor(Color.rgb((int) spec_data[WeightSize], (int) spec_data[WeightSize+1], (int) spec_data[WeightSize+2]));
            series.resetData(data);

    }

    protected void onCancelled(Void result) {
        Log.d("Updates", "I am In Cancelled");
        if (mSensorTask != null)
            mSensorTask.cancel(true);


    }

}
公共类AsyncTaskActivity扩展了AsyncTask{
受保护的void onPreExecute(){
viewport.setMinY(0);
viewport.setMaxY(8000);
viewport.setMinX(0);
viewport.setMaxX(330);
StaticLabelFormatter=新的StaticLabelFormatter(图形);
SetHorizontalLabelFormatter.setHorizontalLabels(新字符串[]{“400”、“500”、“600”、“730”});
graph.getGridLabelRenderer().setLabelFormatter(StaticLabelFormatter);
} 
受保护的Void doInBackground(Void…参数){
而(!isCancelled()){
已同步(nativeData){
nativeData=getDatafromsensor();//来自本机的数据。
}
publishProgress(null);//这将在UI线程上调用onProgressUpdate
}
}
受保护的void onProgressUpdate(void…值){
///这个
series.setBackgroundColor(Color.rgb((int)spec_数据[WeightSize],(int)spec_数据[WeightSize+1],(int)spec_数据[WeightSize+2]);
系列。重置数据(数据);
public class AsyncTaskActivity extends AsyncTask<Void, Double, Void> {


    protected void onPreExecute() {
            viewport.setMinY(0);
            viewport.setMaxY(8000);
            viewport.setMinX(0);
            viewport.setMaxX(330);
            staticLabelsFormatter = new StaticLabelsFormatter(graph);
            staticLabelsFormatter.setHorizontalLabels(new String[]{"400", "500", "600", "730"});
            graph.getGridLabelRenderer().setLabelFormatter(staticLabelsFormatter);

        } 


    protected Void doInBackground(Void... params) {

        while (!isCancelled()) {
            synchronized (nativeData) {
            nativeData = getDatafromsensor(); // Data from native.
        }
        publishProgress(null);  // this invokes onProgressUpdate on UI thread
    }
    }

    protected void onProgressUpdate(Void... values) {

///This one here
            series.setBackgroundColor(Color.rgb((int) spec_data[WeightSize], (int) spec_data[WeightSize+1], (int) spec_data[WeightSize+2]));
            series.resetData(data);

    }

    protected void onCancelled(Void result) {
        Log.d("Updates", "I am In Cancelled");
        if (mSensorTask != null)
            mSensorTask.cancel(true);


    }

}