初始化onCreate视图的首选方法是什么?

时间:2014-11-19 19:44:59

标签: android android-asynctask genymotion

简短版本:是否可以在OnCreate()期间设置视图的内容,或者在OnCreate()期间更好地将其作为ASyncTask执行?是否有类似于OnPostCreate()的东西?

我发现当我使用模拟器(默认和Genymotion模拟器)运行我的应用程序时,启动新任务似乎非常缓慢,我经常看到日志注意到丢帧(UI线程可能做了太多工作! )。有时,Genymotion模拟器甚至会提示我的应用程序没有响应,并且有一个等待/强制关闭对话框。

我使用Parcelable在我的活动之间传递数据作为Bundle。数据是一个简单的集合,包含大约十几个整数和字符串。似乎传递这个捆绑包会减慢速度。

当我使用我的三星物理安卓设备时,我根本没有注意到任何延迟,但我担心未来的性能命中或设备速度较慢。

提供相关代码

启动活动

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

接收Bundle的Activity是缓慢最明显的地方

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

在上面的代码中,我想知道我是否应该在“更新视图”块中执行ASync任务。但是让我失望的是,这主要是所有UI更新的东西,并且觉得它应该在这个主UI线程上?我错了吗?什么是最干净,最有效的方法?传递捆绑包时初始化视图的正确方法是什么,捆绑性能是否受到影响?或者它是低效仿真器的所有工件?

1 个答案:

答案 0 :(得分:0)

大多数情况下,您正在处理模拟器延迟和性能问题。真实设备可以非常快速地优先处理与UI相关的内容,尤其是在具有更多内核的新模型中。

看起来你在正确的地方做了工作,虽然这里有几条评论:

  1. 您必须在UI线程上执行此操作。您无法“后台处理”UI更新。

  2. 处理捆绑包对UI响应或显示时间几乎没有影响。

  3. 如果你想“测试”这个(因为你可能有特殊情况),你可以将更新放在AsyncTask中,然后在onCreate之后10秒或甚至{{ 1}} - 被调用。 onResume可能与您的“onPostCreate”概念最接近(尽管您还有onResume)。查看活动生命周期:

  4. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

    onStart是一个常见的地方,但是由于您传递数据,您可以考虑使用onCreate但它确实不会对性能产生太大影响。

    1. 如果您真的想尝试这个,可以等到“绘制”布局,然后更新您的视图。您可以使用onResume
    2. 执行此操作

      How can you tell when a layout has been drawn?