In the Oscilloscope Activity, communication with the PSLab device goes in parallel with updations of the graph which result in inoperable UI if both these functions are performed in the main thread. This would severely degrade the user experience. In order to avoid this, we simply used AsyncTask. AsyncTasks are used to perform communications with the device in the background thread and update UI when the task in background thread completes. AsyncTask thus solves the problem of making UI super laggy while performing certain time-consuming functions. The UI remains responsive throughout.
More about AsyncTask
AsyncTask is an abstract Android class which helps the Android applications to handle the Main UI thread in a more efficient way. AsyncTask class allows to perform long lasting background operations and update the results in UI thread without affecting the main thread.
Implementing AsyncTask in Android applications
- Create a new class inside Activity class and extend AsyncTask:
private class Task extends AsyncTask<Void, Void, Void> { protected Long doInBackground(aVoid) { } protected void onProgressUpdate(aVoid) { } protected void onPostExecute(aVoid) { } }
- Execute the task:
new Task().execute();
How they are used in Oscilloscope Activity?
The following diagram explains how AsyncTasks are used in Oscilloscope Activity.
AsyncTask in PSLab Android App
A public class extending AsyncTask is defined, this task is executed from another thread.
public class Task extends AsyncTask<String, Void, Void> { ArrayList<Entry> entries; String analogInput;
doInBackgroundMethod performs the part related to communication with the PSLab device.
Here we are capturing the data from the hardware using captureTraces and fetchTraces method.
@Override protected Void doInBackground(String... params) { try { analogInput = params[0]; //no. of samples and timegap still need to be determined scienceLab.captureTraces(1, 800, 10, analogInput, false, null); Log.v("Sleep Time", "" + (800 * 10 * 1e-3)); Thread.sleep((long) (800 * 10 * 1e-3)); HashMap<String, double[]> data = scienceLab.fetchTrace(1); //fetching data double[] xData = data.get("x"); double[] yData = data.get("y"); entries = new ArrayList<Entry>(); for (int i = 0; i < xData.length; i++) { entries.add(new Entry((float) xData[i], (float) yData[i])); } } catch (NullPointerException e){ cancel(true); } catch (InterruptedException e) { e.printStackTrace(); } return null; }
After the thread, completely executed onPostExecute is called to update the UI/graph. This method runs on the main thread.
@Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); LineDataSet dataset = new LineDataSet(entries, analogInput); LineData lineData = new LineData(dataset); dataset.setDrawCircles(false); mChart.setData(lineData); mChart.invalidate(); //refresh the chart synchronized (lock){ lock.notify(); } } }
This simply solves the problem of lags and the Oscilloscope works like a charm.