Android 如何正确应用异步任务?

Android 如何正确应用异步任务?,android,android-asynctask,store,accelerometer,onclicklistener,Android,Android Asynctask,Store,Accelerometer,Onclicklistener,我正在编写以下代码,我研究了其他问题,如 和 但是我仍然有问题,你能告诉我我错过了什么吗?非常感谢 所以,在UI中我有一个开始按钮,s停止按钮和一个文本视图。 我从加速计传感器获取数据并存储在csv文件中。 如果不使用AsyncTask,代码可以正常工作,但使用它(如下所示)时,我会遇到以下错误:无法将_datatest解析为变量 因此,基本上,我想要的是在单击开始按钮后立即开始在后台写入加速计数据,然后单击停止按钮后,文本视图显示“数据已存储!” 谢谢你的帮助 import java.io.F

我正在编写以下代码,我研究了其他问题,如 和 但是我仍然有问题,你能告诉我我错过了什么吗?非常感谢

所以,在UI中我有一个开始按钮,s停止按钮和一个文本视图。 我从加速计传感器获取数据并存储在csv文件中。 如果不使用AsyncTask,代码可以正常工作,但使用它(如下所示)时,我会遇到以下错误:无法将_datatest解析为变量

因此,基本上,我想要的是在单击开始按钮后立即开始在后台写入加速计数据,然后单击停止按钮后,文本视图显示“数据已存储!”

谢谢你的帮助

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Criteria;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener, OnClickListener {

    private SensorManager sensorManager;
    private LocationManager locationManager;
    private Button start_bt;
    private Button stop_bt;
    private TextView result_view;
    private boolean started = false;
    String towers;    
    FileOutputStream fos;
    String FILENAME = "AccelOutput";

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

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria crit = new Criteria();
        towers = locationManager.getBestProvider(crit, false);
        start_bt = (Button) findViewById(R.id.startButton);
        stop_bt = (Button) findViewById(R.id.stopButton);
        result_view = (TextView) findViewById(R.id.resultTextView);
        start_bt.setOnClickListener(this);
        stop_bt.setOnClickListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

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

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (started) {
            Sensor sensortype = event.sensor;

            if (sensortype.getType() == Sensor.TYPE_ACCELEROMETER) {

                double a_x = event.values[0];
                double a_y = event.values[1];
                double a_z = event.values[2];
                double a_a = event.accuracy;
                double a_ts = event.timestamp;
                long a_timestamp = System.currentTimeMillis();
                AccelData a_data = new AccelData(a_timestamp, a_ts, a_x, a_y, a_z, a_a);                
                String a_datatest = a_data.toString();

                new writeData().execute();
            }       
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.startButton) {
            started = true;
            Sensor accel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            sensorManager.registerListener(this, accel, SensorManager.SENSOR_DELAY_FASTEST);
        } else if(v.getId() == R.id.stopButton) {
            started = false;
            sensorManager.unregisterListener(this);
        }
    }

    private class writeData extends AsyncTask<Void, Void, String>{

        @Override
        protected String doInBackground(Void... params) {
            // TODO Auto-generated method stub
            File sdCard = Environment.getExternalStorageDirectory();
            File directory = new File (sdCard.getAbsolutePath() + "/output");
            directory.mkdirs();

            String a_filename = "accelerometer.csv";
            File a_file = new File(directory, a_filename);
            FileOutputStream a_fOut = null;
            try {
                a_fOut = new FileOutputStream(a_file, true);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            OutputStreamWriter a_osw = new OutputStreamWriter(a_fOut);
            try {
                a_osw.write(a_datatest + "\n");
                a_osw.flush();
                a_osw.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
              result_view.setText("Data Stored!"); 
        }
    }
}
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.OutputStreamWriter;
导入android.hardware.Sensor;
导入android.hardware.SensorEvent;
导入android.hardware.SensorEventListener;
导入android.hardware.SensorManager;
导入android.location.Criteria;
导入android.location.LocationManager;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.os.Environment;
导入android.app.Activity;
导入android.content.Context;
导入android.view.Menu;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.widget.Button;
导入android.widget.TextView;
公共类MainActivity扩展活动实现SensorEventListener、OnClickListener{
私人传感器管理器传感器管理器;
私人场所经理场所经理;
私人按钮启动;
私人按钮停止;
私有文本视图结果_视图;
private boolean start=false;
弦塔;
文件输出流;
字符串FILENAME=“AccelOutput”;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager=(sensorManager)getSystemService(Context.SENSOR\u服务);
locationManager=(locationManager)getSystemService(Context.LOCATION\u服务);
Criteria crit=新标准();
towers=locationManager.getBestProvider(crit,false);
开始按钮=(按钮)findViewById(R.id.startButton);
停止按钮=(按钮)findViewById(R.id.stopButton);
结果\视图=(TextView)findViewById(R.id.resultTextView);
启动_bt.setOnClickListener(此);
stop_bt.setOnClickListener(此);
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
getMenuInflater().充气(R.menu.main,menu);
返回true;
}
@凌驾
精度已更改(传感器,int精度){
}
@凌驾
传感器更改时的公共无效(传感器事件){
如果(启动){
传感器类型=event.Sensor;
if(sensortype.getType()==Sensor.TYPE\u加速计){
双a_x=事件值[0];
双a_y=事件值[1];
双a_z=事件值[2];
双a_a=事件精度;
双a_ts=event.timestamp;
长时间戳=System.currentTimeMillis();
AccelData a_data=新的AccelData(a_时间戳、a_ts、a_x、a_y、a_z、a_a);
字符串a_datatest=a_data.toString();
新建writeData().execute();
}       
}
}
@凌驾
公共void onClick(视图v){
if(v.getId()==R.id.startButton){
开始=真;
传感器加速度=sensorManager.getDefaultSensor(传感器类型\加速计);
sensorManager.registerListener(此、accel、sensorManager.SENSOR\u DELAY\u最快);
}else if(v.getId()==R.id.stopButton){
开始=错误;
sensorManager.UnregistereListener(此);
}
}
私有类writeData扩展异步任务{
@凌驾
受保护字符串doInBackground(无效…参数){
//TODO自动生成的方法存根
文件sdCard=Environment.getExternalStorageDirectory();
文件目录=新文件(sdCard.getAbsolutePath()+“/output”);
mkdirs()目录;
字符串a_filename=“Accelerator.csv”;
File a_File=新文件(目录,a_文件名);
FileOutputStream a_fOut=null;
试一试{
a_fOut=新文件输出流(a_文件,true);
}catch(filenotfounde异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
OutputStreamWriter a_osw=新的OutputStreamWriter(a_fOut);
试一试{
a_osw.write(a_datatest+“\n”);
a_osw.flush();
a_osw.close();
}捕获(IOE异常){
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onPostExecute(字符串结果){
result_view.setText(“存储的数据!”);
}
}
}

在类范围内声明变量。i、 e将其用作成员变量

您正在
onSensorChanged
方法中声明
a_datatest
,因此它在此范围之外没有有效性。因此,您不能在
doInBackGround
方法中使用它

在班里照顾像

private String a_datatest;
在onSensorChanged方法中,使用like

a_datatest = a_data.toString();

我不认为
AsyncTask
是完成此任务的最佳方式<代码>异步任务设计用于一次性操作,例如从服务器下载一组数据。
AsyncTask
启动,在后台执行某些操作,然后向UI线程报告。虽然可以停止
AsyncTask
任务,但它不能按您想要的方式工作

我建议只使用
服务
。你可以成为明星