2017-04-12 63 views
0

我有一個REST服務器,它從遠程ADC中吐出數據,並且我需要繪製數據以進行演示。我使用AsyncTask將數據採集從主線程移開以防止NetworkOnMainThreadException。我寫了這個:即使在對象重新創建後設備旋轉後,AsyncTask也不會啓動

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; 
    } 

} 

有一個從MPAndroidCharts Activity上LineChart和的AsyncTask應該更新它從服務器獲取新的圖表數據的UI。但是,在設備旋轉之後,調用GraphWorker的方法調用對象狀態後,調用​​之後,將永遠不會調用或運行doInBackground()。爲什麼?

回答

0

在開始另一個工作之前,我需要停止以前的工作。

在順序處理中,所有異步任務都在單個線程中運行,因此必須等上一個任務結束之前。如果您需要立即執行代碼,則需要在單獨的線程中並行處理任務。

因此,在prepareResume中添加running=false以阻止以前的工作人員解決此問題。

相關問題