2017-04-12 4 views
0

リモートADCからのデータを吐き出すRESTサーバーがあり、プレゼンテーションのためにデータをグラフ化する必要があります。私は、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からLineChartで、AsyncTaskは、それがサーバから取得する新しいチャートデータとUIを更新することになっている:私はこれを書きました。ただし、デバイスの回転後、GraphWorkerresume()メソッドが呼び出されてオブジェクト状態が復元された後、​​を呼び出した後では、doInBackground()は呼び出されず、実行されません。どうして?

答えて

0

別の作業を開始する前に前の作業者を停止する必要があります。

すべての非同期タスクは単一のスレッドで実行されるため、前のタスクが終了するまで待機する必要があります。すぐにコードを実行する必要がある場合は、タスクを別々のスレッドで並列に処理する必要があります。

したがって、running=falseprepareResumeに追加すると、以前の作業者がこの問題を解決します。

関連する問題