Android 即使在对象重新创建后,设备旋转后也不会启动AsyncTask
我有一个REST服务器,它可以从远程ADC中输出数据,我需要将数据绘制成图形,以便演示。我使用AsyncTask将数据获取移出主线程,以防止NetworkOnMainThreadException。我写道: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
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
以停止前一个工作进程可以解决此问题