2014-11-19 2 views
0

Краткая версия: Предполагается ли установить содержимое просмотров во время OnCreate(), или лучше сделать это как ASyncTask во время OnCreate()? есть ли что-то похожее на OnPostCreate()?Каков предпочтительный способ инициализации представлений onCreate?

Я обнаружил, что когда я запускаю свое приложение с использованием эмулятора (как эмулятора по умолчанию, так и эмулятора Genymotion), запуск новых задач кажется действительно вялым, и я часто вижу журнал, замеченный об отбрасывании кадров (поток пользовательского интерфейса может делать слишком много работы !). Иногда эмулятор Genymotion даже дает подсказку о том, что мое приложение не реагирует и диалог Wait/Force Close.

Передаю данные между моей деятельностью как Пакет, используя Parcelable. Данные представляют собой простой набор из примерно дюжины целых чисел и строк. кажется, что передача этого пакета - это то, что замедляет работу.

Когда я использую свое физическое устройство Android для Android, я вообще не замечаю никаких задержек, но я беспокоюсь о будущих хитах производительности или более медленных устройствах.

Соответствующий код поставляется

Запускает активность

Intent intent = new Intent(this, edit.class); 
    intent.putExtra(SoundConfig.class.getName(), sc); 

    startActivityForResult(intent, buttonID); 

Parcelable объект

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 где медлительность является наиболее очевидным

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, и чувствуете, что это должно быть в этом главном потоке пользовательского интерфейса? Я ошибаюсь? Какой самый чистый и эффективный способ сделать это? Каков правильный способ инициализации представлений при передаче пакета и связывает ли производительность? Или это все артефакты неэффективного эмулятора?

+0

Я вижу «нить UI может делать слишком много работы!» все время в моих журналах. Даже когда я запускаю что-то простое. Я бы действительно не беспокоился о том, что переводится на ваше приложение, работающее на самом устройстве. Я не вижу, как бы облегчить настройку представлений в asynctask, так как вам все равно придется дождаться окончания, чтобы отобразить ваше представление. –

ответ

0

Скорее всего, вы имеете дело с проблемами с эмулятором и проблемами производительности. Реальные устройства высоко оценивают материал, связанный с пользовательским интерфейсом, особенно в новых моделях с большим количеством ядер.

Похоже, что вы делаете работу в нужном месте, хотя и здесь есть пара комментариев:

  1. Вы должны сделать это в потоке пользовательского интерфейса. Вы не можете обновлять пользовательские интерфейсы «фонового процесса».

  2. Обработка пакета оказывает малое влияние на отзывчивость пользовательского интерфейса или время отображения.

  3. Если вы хотите «тест» это (потому что, может быть, у вас есть особое положение), вы можете поставить обновление в качестве AsyncTask, а затем сделать это, может быть, через 10 секунд после onCreate - или даже onResume - называется. onResume может быть самым близким к вашей концепции «onPostCreate» (хотя у вас также есть onStart). Посмотрите на жизнь Активность цикла:

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

onCreate является общим местом, чтобы поместить это, однако, так как вы передаете данные, вы можете рассмотреть возможность использования onResume, но это действительно не будет иметь большого влияния на производительность ,

  1. Если вы действительно хотите попробовать это, вы можете подождать, пока макет будет «нарисован», а затем обновите свои представления. Вы можете сделать это с viewTreeObserver:

How can you tell when a layout has been drawn?

Смежные вопросы