Значение объекта Android изменено при возобновлении работы

У меня ОЧЕНЬ СТРАННАЯ ситуация ... (мне)

Например, 2 объекта,
1 - это логический член активности с именем isInPage,
2 - статический растровый объект с именем bmpPhoto.

Когда я перейду к своему собственному действию под названием FacebookShareActivity,
isInPage будет истинным, пока я не выйду из этого действия,
bmpPhoto получит изображение.

После onCreare () и onResume () код не запускается, пока пользователь не щелкнет какой-либо графический интерфейс.
Я закрыл экран, нажав аппаратную кнопку питания, и, возможно, подождал 5 или 10 минут.

Хорошо, теперь я снова нажимаю кнопку porwe, чтобы разбудить телефон, разблокировать экран,
и моя FacebookShareActivity вернется на передний план.
И я нажимаю кнопку графического интерфейса, чтобы проверить значение переменной через Logcat, он говорит:

isInPage = false; И я забыл значение bmpPhoto, но в моем графическом интерфейсе фотография просто исчезла,
больше не отображается ...



Как это случилось?
И это происходит не каждый раз после того, как я это сделаю ......


Что если я переопределю onSaveInstanceState (Bundle savedInstanceState) и
onRestoreInstanceState (Bundle savedInstanceState)?
Это поможет?
А как насчет растрового объекта?


Все еще не знаю, как это случилось ...
Я что-то пропустил?


Мне очень нужна ваша помощь, пожалуйста, всем ~

Ниже приводится часть моего кода, довольно длинная ... «isPageRunning» и «bmp» менялись иногда, когда возвращались с рабочего стола, но не каждый раз.

public class FacebookShareActivity extends Activity
{
  private Bundle b=null;
  private Bitmap bmp=null;
  private boolean isFacebookWorking=false;
  private boolean isPageRunning=true; //This value sometime changed when back from desktop, but not every time

  protected void onCreate(Bundle savedInstanceState)
  {
    Log.i(Constants.TAG, "ON Facebook Share create......");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.facebook_share);
    setVolumeControlStream(AudioManager.STREAM_MUSIC);
  }

  private void initUI()
  {
    btnBack=(Button)findViewById(R.id.btnBack);
    btnBack.setOnClickListener(new ButtonClickHandler());

    formImage=(RelativeLayout)findViewById(R.id.form_image);
    formImage.setDrawingCacheEnabled(true);

    btnShare=(Button)findViewById(R.id.btnShare);
    btnShare.setOnClickListener(new ButtonClickHandler());

    txtIntroText=(TextView)findViewById(R.id.txtIntroText);
    txtIntroText.setOnClickListener(new ButtonClickHandler());
    txtIntroText.setText(getUploadInImageText());

    photo=(ImageView)findViewById(R.id.photo);
    bmp=Constants.PROFILE.getName().getPhoto();
    if(bmp!=null)
    {photo.setImageBitmap(bmp);} //bmp wouldn't be null, it filled by some other activity before
  }

  @Override
  protected void onResume()
  {
    super.onResume();
    Log.i(Constants.TAG, "Trying to set UI on resume...");
    b=getIntent().getExtras();
    // ...
    // ... Get some String value passed from prev activity

    facebook=new Facebook("123456789012345"); //Test
    asyncFacebook=new AsyncFacebookRunner(facebook);

    initUI();
    System.gc();
  }

  @Override
  public void onBackPressed()
  {
    Log.d(Constants.TAG, "Activity receive back key...");
    lockButtons(false);
    return;
  }

  private void lockButtons(boolean b)
  {
    if(isPageRunning)
    {
      btnBack.setClickable(!b);
      btnShare.setClickable(!b);
    }
  }

  private class DelayReleaseKey implements Runnable
  {
    public void run()
    {
      try{Thread.sleep(10000);}
      catch(InterruptedException ie){}
      handler.sendEmptyMessage(0);
    }
  }

  private class ButtonClickHandler implements OnClickListener
  {
    public void onClick(View v)
    {
      if(v==btnBack)
      {
        if(isFacebookWorking)
        {ShowAlertDialog(Constants.MESSAGE_FACEBOOK_WORK);}
        else
        {
          lockButtons(true);
          formImage=null;
          photo=null;
          b=null;
          facebook=null;
          isPageRunning=false;
          Intent intent=new Intent(FacebookShareActivity.this, PracticeListActivity.class);
          startActivity(intent);
          FacebookShareActivity.this.finish();
          overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);
        }
      }
      if(v==btnShare)
      {
        lockButtons(true);
        facebookLogin();
      }
    }
  }
}

Теперь я знаю, что должен переопределить onSaveInstanceState, onRestoreInstanceState. Они могут помочь мне сохранить такие переменные, как String, int, boolean ... А как насчет Bitmap? А что, если моя переменная статическая?


person RRTW    schedule 05.12.2011    source источник
comment
RRTW, посмотрите это   -  person Phil    schedule 05.12.2011
comment
где вы устанавливаете логическое значение и изображение? Это onCreate? А еще можно вставить фрагмент кода?   -  person havexz    schedule 05.12.2011
comment
Нам нужен код. Похоже, вы не сохраняете состояние своего Activity, поэтому, когда он убивается и перезапускается, он больше не имеет своего предыдущего состояния. Отправьте код для своего Activity, чтобы мы могли проверить.   -  person dave.c    schedule 05.12.2011


Ответы (2)


А теперь попробуйте еще раз.

public class FacebookShareActivity extends Activity
{
  private Bundle b=null;
  private static Bitmap bmp=null;
  private static boolean isFacebookWorking=false;
  private static boolean isPageRunning=true; //This value sometime changed when back from desktop, but not every time

  protected void onCreate(Bundle savedInstanceState)
  {
    Log.i(Constants.TAG, "ON Facebook Share create......");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.facebook_share);
    setVolumeControlStream(AudioManager.STREAM_MUSIC);
  }

  private void initUI()
  {
    btnBack=(Button)findViewById(R.id.btnBack);
    btnBack.setOnClickListener(new ButtonClickHandler());

    formImage=(RelativeLayout)findViewById(R.id.form_image);
    formImage.setDrawingCacheEnabled(true);

    btnShare=(Button)findViewById(R.id.btnShare);
    btnShare.setOnClickListener(new ButtonClickHandler());

    txtIntroText=(TextView)findViewById(R.id.txtIntroText);
    txtIntroText.setOnClickListener(new ButtonClickHandler());
    txtIntroText.setText(getUploadInImageText());

    photo=(ImageView)findViewById(R.id.photo);
    bmp=Constants.PROFILE.getName().getPhoto();
    if(bmp!=null)
    {photo.setImageBitmap(bmp);} //bmp wouldn't be null, it filled by some other activity before
  }

  @Override
  protected void onResume()
  {
    super.onResume();
    isPageRunning = true;
    Log.i(Constants.TAG, "Trying to set UI on resume...");
    b=getIntent().getExtras();
    // ...
    // ... Get some String value passed from prev activity

    facebook=new Facebook("123456789012345"); //Test
    asyncFacebook=new AsyncFacebookRunner(facebook);

    initUI();
    System.gc();
  }

  @Override
  protected void onPause()
  {
        isPageRunning = false;
  }


  @Override
  public void onBackPressed()
  {
    Log.d(Constants.TAG, "Activity receive back key...");
    lockButtons(false);
    return;
  }

  private void lockButtons(boolean b)
  {
    if(isPageRunning)
    {
      btnBack.setClickable(!b);
      btnShare.setClickable(!b);
    }
  }

  private class DelayReleaseKey implements Runnable
  {
    public void run()
    {
      try{Thread.sleep(10000);}
      catch(InterruptedException ie){}
      handler.sendEmptyMessage(0);
    }
  }

  private class ButtonClickHandler implements OnClickListener
  {
    public void onClick(View v)
    {
      if(v==btnBack)
      {
        if(isFacebookWorking)
        {ShowAlertDialog(Constants.MESSAGE_FACEBOOK_WORK);}
        else
        {
          lockButtons(true);
          formImage=null;
          photo=null;
          b=null;
          facebook=null;
          isPageRunning=false;
          Intent intent=new Intent(FacebookShareActivity.this, PracticeListActivity.class);
          startActivity(intent);
          FacebookShareActivity.this.finish();
          overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);
        }
      }
      if(v==btnShare)
      {
        lockButtons(true);
        facebookLogin();
      }
    }
  }
}
person jainal    schedule 06.12.2011

Для примитивных значений следует использовать onSaveInstanceState. Для восстановления вы можете использовать onRestoreInstanceState или код в onCreate, например:

if(savedInstanceState != null) {
  // restore old state
} else {
  // a fresh start
}

Теперь для восстановления таких объектов, как Bitmap, если их создание не требует больших затрат и не делает ваш пользовательский интерфейс медленным, создайте их снова при восстановлении. Если вы этого не хотите, используйте onRetainNonConfigurationInstance, и код будет выглядеть так:

@Override
public Object onRetainNonConfigurationInstance () {
  return bmp;
}

@Override
public void onCreate() {
  if
  bmp = (Bitmap)getLastNonConfigurationInstance();
}

ВНИМАНИЕ: этот api устарел, вы можете использовать его на старых платформах. Я поместил это здесь для иллюстрации. Новый способ сделать это более интересен.

Вот подробная ссылка:

getLastNonConfigurationInstance

onRetainNonConfigurationInstance

person havexz    schedule 06.12.2011
comment
Я до сих пор не знаю точно о вашем сообщении (извините, я не очень хорошо говорю по-английски, но я постараюсь следить за вами), но теперь я думаю, что ... Когда другое приложение попросило больше ОЗУ и android ОС очищает оперативную память, которую использовала моя деятельность, узнаю ли я об этом? Например, будет ли вызываться onLowMemory ()? Думаю, так и должно быть, но не уверен ... - person RRTW; 06.12.2011
comment
Да, вы можете узнать об этом. Вы должны использовать BroadcastRecievers и попытаться поймать ACTION_DEVICE_STORAGE_LOW Вот ссылка: разработчик .android.com / reference / android / content / developer.android .com / reference / android / content / developer.android .com / guide / themes / intents / intents-filters.html. - person havexz; 06.12.2011