Android 即使在对象重新创建后,设备旋转后也不会启动AsyncTask

Android 即使在对象重新创建后,设备旋转后也不会启动AsyncTask,android,android-asynctask,Android,Android Asynctask,我有一个REST服务器,它可以从远程ADC中输出数据,我需要将数据绘制成图形,以便演示。我使用AsyncTask将数据获取移出主线程,以防止NetworkOnMainThreadException。我写道: package inostiot.inostiot; // imports public class MonitorActivity extends AppCompatActivity { private GraphWorker worker; @Override

我有一个REST服务器,它可以从远程ADC中输出数据,我需要将数据绘制成图形,以便演示。我使用AsyncTask将数据获取移出主线程,以防止NetworkOnMainThreadException。我写道:

package inostiot.inostiot;

// imports

public class MonitorActivity extends AppCompatActivity {

    private GraphWorker worker;

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        worker.cancel(true);
        outState.putBundle("state", worker.prepareResume());
        outState.putBoolean("resuming", true);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_monitor);

        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        String ip = extras.getString("ip");

        LineChart chart = (LineChart) findViewById(R.id.chart);

        XAxis x = chart.getXAxis();
        YAxis y = chart.getAxisLeft();

        // More chart setup here, ignore

        if (savedInstanceState != null) {

            boolean resuming = savedInstanceState.getBoolean("resuming", false);

            if (resuming) {
                worker = new GraphWorker(this, ip, chart, true);
                worker.resume(savedInstanceState.getBundle("state"));
                worker.execute();
            }

        } else {
            worker = new GraphWorker(this, ip, chart, false);
            worker.execute();
        }
    }
}


class GraphWorker extends AsyncTask<Void, Object, Void> {

    private LineChart chart;
    private boolean resuming;
    private boolean running = true;
    private String ip;
    private Activity parent;

    private ArrayList<ADCPort> ports;
    private ArrayList<WalkingDataset> walkingDatasets;
    private ArrayList<LineDataSet> lineDataSets;

    GraphWorker(Activity parent, String ip, LineChart chart, boolean resuming) {

        this.parent = parent;

        if (!resuming) {
            ports = new ArrayList<>();
            walkingDatasets  = new ArrayList<>();
            this.ip = ip;
        }

        this.chart = chart;
        this.resuming = resuming;
        lineDataSets = new ArrayList<>();


    }

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

        ADC adc = new ADC(ip);

        if (!resuming) {

            if (!adc.auth()) throw new RuntimeException("Server invalid!");

            ports.add(new ColoredADCPort(0, "#FF0000"));
            walkingDatasets.add(new WalkingDataset(10));

            // More ports are initialized here, just copy-paste an
            // color change


        }


        while (running) {

            try {

                ports = adc.readPorts(ports);
                publishProgress((Object)ports);

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            } catch (ADCException e) {
                e.printStackTrace();
                break;
            }

        }

        return null;

    }

    void resume(Bundle data) {
        this.ports = (ArrayList<ADCPort>) data.getSerializable("ports");
        this.walkingDatasets = (ArrayList<WalkingDataset>) data.getSerializable("walkingDatasets");
        this.ip = data.getString("ip");
        this.chart.invalidate();
    }

    Bundle prepareResume() {
        Bundle data = new Bundle();
        data.putSerializable("ports", ports);
        data.putSerializable("walkingDatasets", walkingDatasets);
        data.putString("ip", ip);
        return data;
    }

    @Override
    protected void onProgressUpdate(Object... values) {

        ArrayList<ADCPort> ports = (ArrayList<ADCPort>) values[0];

        lineDataSets.clear();

        for (int i = 0; i < ports.size(); i++) {

            ColoredADCPort port = (ColoredADCPort) ports.get(i);
            WalkingDataset dataset = walkingDatasets.get(i);

            dataset.add(port.getValue());

            LineDataSet lineDataSet = new LineDataSet(dataset, String.format(Locale.ENGLISH, "Sensor %d", i));
            lineDataSet.setCircleColor(Color.parseColor(port.getColor()));
            lineDataSet.setColor(Color.parseColor(port.getColor()));
            lineDataSet.setDrawValues(false);

            lineDataSets.add(lineDataSet);

        }

        final LineData data = new LineData();

        for (LineDataSet set : lineDataSets) {
            data.addDataSet(set);
        }

        chart.setData(data);
        chart.postInvalidate();

        super.onProgressUpdate();
    }

    public void stopRunner() {
        this.running = false;
    }

}
包inostiot.inostiot;
//进口
公共类MonitorActivity扩展了AppCompatActivity{
私人作画工人;
@凌驾
SaveInstanceState上受保护的无效(束超出状态){
worker.cancel(true);
outState.putBundle(“state”,worker.prepareResume());
超出状态。布尔值(“恢复”,真);
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u监视器);
Intent=getIntent();
Bundle extras=intent.getExtras();
字符串ip=extras.getString(“ip”);
折线图=(折线图)findViewById(R.id.chart);
XAxis x=chart.getXAxis();
YAxis y=chart.getAxisLeft();
//此处有更多图表设置,请忽略
如果(savedInstanceState!=null){
boolean resuming=savedInstanceState.getBoolean(“resuming”,false);
如果(恢复){
worker=新的GraphWorker(this、ip、chart、true);
worker.resume(savedInstanceState.getBundle(“state”);
worker.execute();
}
}否则{
worker=新的GraphWorker(this,ip,chart,false);
worker.execute();
}
}
}
类GraphWorker扩展了AsyncTask{
专用线图;
私人布尔恢复;
私有布尔运行=真;
私有字符串ip;
私人活动家长;
专用阵列列表端口;
私有ArrayList WalkingDataSet;
专用ArrayList行数据集;
GraphWorker(活动父级、字符串ip、折线图、布尔恢复){
this.parent=parent;
如果(!正在恢复){
端口=新的ArrayList();
walkingDatasets=newArrayList();
this.ip=ip;
}
this.chart=图表;
这个.恢复=恢复;
lineDataSets=newarraylist();
}
@凌驾
公共Void doInBackground(Void…params){
ADC=新的ADC(ip);
如果(!正在恢复){
如果(!adc.auth())抛出新的RuntimeException(“服务器无效!”);
添加(新的彩色数据端口(0,#FF0000”);
添加(新的WalkingDataset(10));
//这里初始化了更多端口,只需复制粘贴
//变色
}
(跑步时){
试一试{
端口=adc.readPorts(端口);
publishProgress((对象)端口);
试一试{
睡眠(1000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}捕获(ADCEException e){
e、 printStackTrace();
打破
}
}
返回null;
}
作废恢复(捆绑数据){
this.ports=(ArrayList)data.getSerializable(“端口”);
this.walkingDatasets=(ArrayList)data.getSerializable(“walkingDatasets”);
this.ip=data.getString(“ip”);
这个.chart.invalidate();
}
捆绑准备费用(){
Bundle data=新Bundle();
数据。可串行化(“端口”,端口);
数据.putSerializable(“walkingDatasets”,walkingDatasets);
数据字符串(“ip”,ip);
返回数据;
}
@凌驾
受保护的void onProgressUpdate(对象…值){
ArrayList端口=(ArrayList)值[0];
lineDataSets.clear();
对于(int i=0;i

活动上有一个来自
MPAndroidCharts
LineChart
,异步任务应该使用从服务器获取的新图表数据更新UI。但是,在设备旋转之后以及调用
GraphWorker
resume()
方法来恢复对象状态之后,在调用
execute()
之后,
doInBackground()
从未被调用或正在运行。为什么?

在启动另一个工作程序之前,我需要停止上一个工作程序

在顺序处理中,所有异步任务都在单个线程中运行,因此必须在前一个任务结束之前等待。如果需要立即执行代码,则需要在单独的线程中并行处理任务

因此,在
prepareResume
中添加
running=false
以停止前一个工作进程可以解决此问题