Short version: Is it perfered to set the contents of views during OnCreate(), or is it better to do this as an ASyncTask during OnCreate()? is there a something analogous to a OnPostCreate()?
I have found that when I run my app using the emulator (both default and Genymotion emulator) that starting new tasks seems really sluggish, and I often see log noticed about dropping frames (the UI thread might be doing too much work!). Sometimes the Genymotion emulator even gives a prompt that my app is non-responsive and a Wait/Force Close dialog.
I pass data between my activity as a Bundle, using Parcelable. The data is a simple collection of about a dozen ints and strings. it seems like passing this bundle is what slows things down.
When I use my Samsung physical android device, I don't notice any delay at all, but I worry about future performance hits or slower devices.
Relevant code supplied
Starts the Activity
Intent intent = new Intent(this, edit.class);
intent.putExtra(SoundConfig.class.getName(), sc);
startActivityForResult(intent, buttonID);
Parcelable object
public class SoundConfig implements Parcelable {
public String mediaPath = null;
public int volume = 0;
public int viewID = 0;
public String text = null;
private int loop = 0;
private int holdable = 0;
private int fadeout = 0;
public String boardID = null;
public int colorbase = 0;
public int coloract = 0;
...
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeString(mediaPath);
dest.writeInt(volume);
dest.writeInt(viewID);
dest.writeString(text);
dest.writeInt(loop);
dest.writeString(boardID);
dest.writeInt(holdable);
dest.writeInt(fadeout);
dest.writeInt(colorbase);
}
private void readFromParcel(Parcel in)
{
mediaPath = in.readString();
volume = in.readInt();
viewID = in.readInt();
text = in.readString();
loop = in.readInt();
boardID = in.readString();
holdable = in.readInt();
fadeout = in.readInt();
colorbase = in.readInt();
}
The Activity that receives the Bundle is where the slowness is most obvious
public class edit extends Activity implements ColorPicker.OnColorChangedListener
{
SoundConfig _state = null;
TextView _txtText = null;
TextView _txtFile = null;
SeekBar _cntrlVol = null;
CheckBox _switchLoop = null;
CheckBox _switchToggle = null;
CheckBox _switchFade = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
Bundle bun = getIntent().getExtras();
SoundConfig incomingConfig = null;
if ( bun != null)
{
incomingConfig = bun.getParcelable(SoundConfig.class.getName());
}
else
{
incomingConfig = new SoundConfig();
}
try
{
setTitle("Edit:" + incomingConfig.text);
_state = incomingConfig;
_txtText = (TextView) findViewById(R.id.dispName);
_txtFile = (TextView) findViewById(R.id.dispFile);
_cntrlVol = (SeekBar) findViewById(R.id.skVolume);
_cntrlVol.setOnSeekBarChangeListener(volumeListner);
_switchLoop = (CheckBox) findViewById(R.id.btnSetLoop);
_switchToggle = (CheckBox) findViewById(R.id.btnSetToggle);
_switchFade = (CheckBox) findViewById(R.id.btnSetFade);
...
//Update the views based on info from _state
_txtText.setText(_state.text);
File file = new File(_state.mediaPath);
String trimmed = file.getName().toString();
_txtFile.setText(trimmed);
_cntrlVol.setProgress(_state.volume);
_switchLoop.setChecked(_state.isLoop());
_switchToggle.setChecked(_state.isHoldable());
_switchFade.setChecked(_state.isFadeOut());
}
catch(Exception err)
{
Log.e(tag, "Error " + err.getMessage());
}
}
In my above code, I am wondering if I should be doing the 'Update views' block to be in an ASync task. But what throws me off, is that this is mostly all UI update stuff, and feel like it ought to be on this main UI thread? Am I wrong? What's the cleanest and most efficient way to do this? What is the right way to initialize views when passed a bundle, and are bundles a performance hit? Or is it all artifacts of the inefficient emulator?