සුරකින උදාහරණ තත්වය භාවිතයෙන් ක්‍රියාකාරකම් තත්වයක් සුරැකෙන්නේ කෙසේද?


2624

මම ඇන්ඩ්‍රොයිඩ් එස්ඩීකේ වේදිකාවේ වැඩ කර ඇති අතර, යෙදුමේ තත්වය සුරැකෙන්නේ කෙසේද යන්න ටිකක් අපැහැදිලි ය. එබැවින් 'හෙලෝ, ඇන්ඩ්‍රොයිඩ්' උදාහරණයේ මෙම සුළු නැවත මෙවලම් ලබා දීම:

package com.android.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {

  private TextView mTextView = null;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTextView = new TextView(this);

    if (savedInstanceState == null) {
       mTextView.setText("Welcome to HelloAndroid!");
    } else {
       mTextView.setText("Welcome back.");
    }

    setContentView(mTextView);
  }
}

සරලම අවස්ථාව සඳහා එය ප්‍රමාණවත් යැයි මම සිතුවෙමි, නමුත් එය යෙදුමෙන් away ත් වූ ආකාරය කුමක් වුවත් සෑම විටම පළමු පණිවිඩය සමඟ ප්‍රතිචාර දක්වයි.

මට විශ්වාසයි විසඳුම ඉක්මවා යාම onPauseහෝ ඒ හා සමාන දෙයක්, නමුත් මම විනාඩි 30 ක් හෝ ඊට වැඩි කාලයක් තිස්සේ ලියකියවිලි ඉවතට ඇදගෙන ගොස් ඇති අතර පැහැදිලි කිසිවක් සොයාගෙන නැත.


9
සුරැකෙන්නේ කවදාද?
ට්‍රෝජන්.සොබොට්

90
ඔබ කියූ පරිදි, ඔබ එබීමෙන් සැරිසැරීම, එනම් ඔබන්න. ඇත්ත වශයෙන්ම, මෙම 'saveInstanceState' භාවිතා කරන අවස්ථාව නම්, විනෝදාස්වාදය සඳහා ඇන්ඩ්‍රොයිඩ් ඔබගේ ක්‍රියාකාරකම් විනාශ කරන අවස්ථාවයි. අභිප්‍රාය සඳහා: ක්‍රියාකාරකම ක්‍රියාත්මක වන අතරතුර ඔබ ඔබගේ දුරකථනයේ භාෂාව වෙනස් කරන්නේ නම් (ඔබේ ව්‍යාපෘතියෙන් වෙනස් සම්පත් පූරණය කළ යුතුය). තවත් ඉතා සුලභ සිදුවීමක් නම්, ඔබ ඔබේ දුරකථනය පැත්තට කරකවන විට ක්‍රියාකාරකම ප්‍රතිනිර්මාණය කර භූ දර්ශනයේ ප්‍රදර්ශනය කිරීමයි.
විලෝරන්

16
දෙවන පණිවිඩය ලබා ගැනීම සඳහා, dev විකල්පයන්හි "ක්‍රියාකාරකම් තබා නොගන්න" සක්‍රීය කරන්න. නිවසේ බොත්තමක් ඔබාගෙන පසුබෑමෙන් ආපසු යන්න.
යාරොස්ලාව් මයිට්කාලික්

5
මෙය ඉතා ප්රයෝජනවත් වේ developer.android.com/training/basics/activity-lifecycle/...
සයිඩ් රාසා Mehdi

6
ඔබට මෙය කළ හැකිය: onSaveInstanceState (Bundle saveInstanceState)
VahidHoseini

Answers:


2571

ඔබට මෙවැනි පරාමිතියකට onSaveInstanceState(Bundle savedInstanceState)වෙනස් කිරීමට අවශ්‍ය යෙදුම් තත්ව අගයන් අභිබවා ලිවිය යුතුය Bundle:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
  super.onSaveInstanceState(savedInstanceState);
  // Save UI state changes to the savedInstanceState.
  // This bundle will be passed to onCreate if the process is
  // killed and restarted.
  savedInstanceState.putBoolean("MyBoolean", true);
  savedInstanceState.putDouble("myDouble", 1.9);
  savedInstanceState.putInt("MyInt", 1);
  savedInstanceState.putString("MyString", "Welcome back to Android");
  // etc.
}

මෙම පැකේජය, අවශ්යයෙන්ම NVP ( "නම-අගය යුගල") සිතියම ගබඩා කිරීමේ එක් ක්රමයක් වන අතර, ඒ සඳහා සම්මත වනු ඇත onCreate()onRestoreInstanceState()ඔබ මේ වගේ ක්රියාකාරකම් ලද අගයන් ලබා ගැනීම කරනු ඇත,:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  // Restore UI state from the savedInstanceState.
  // This bundle has also been passed to onCreate.
  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
  double myDouble = savedInstanceState.getDouble("myDouble");
  int myInt = savedInstanceState.getInt("MyInt");
  String myString = savedInstanceState.getString("MyString");
}

නැත්නම් කැබැල්ලකින්.

@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    super.onViewStateRestored(savedInstanceState);
    // Restore UI state from the savedInstanceState.
    // This bundle has also been passed to onCreate.
    boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
    double myDouble = savedInstanceState.getDouble("myDouble");
    int myInt = savedInstanceState.getInt("MyInt");
    String myString = savedInstanceState.getString("MyString");
}

ඔබගේ යෙදුම සඳහා නිදර්ශන අගයන් ගබඩා කිරීම සඳහා ඔබ සාමාන්‍යයෙන් මෙම තාක්ෂණය භාවිතා කරනු ඇත (තේරීම්, සුරකින ලද පෙළ ආදිය).


24
මෙය දුරකථනයෙන් ක්‍රියාත්මක වන ඕනෑම අවස්ථාවක්, නමුත් ඉමුලේටරය තුළ නොවේද? මට ශුන්‍ය නොවන සුරකින ලද ඉන්ස්ටැන්ස්ටේට් එකක් ලබා ගත නොහැක.
ඇඩම් ජැක්

491
සැලකිලිමත් වන්න: ඔබේ අගයන් බණ්ඩලයට එක් කිරීමට පෙර ඔබ super.onSaveInstanceState (saveInstanceState) අමතන්න, නැතහොත් ඒවා එම ඇමතුමෙන් අතුගා දමනු ඇත (Droid X Android 2.2).
jkschneider

121
ප්‍රවේශම් වන්න: නිල ලියකියවිලි වල සඳහන් වන්නේ, ඔබ වැදගත් තොරතුරු onPause-Method තුළ සුරැකිය යුතු බැවින් onaveinstance- ක්‍රමය ඇන්ඩ්‍රොයිඩ් ජීවන චක්‍රයේ කොටසක් නොවන බවයි. developer.android.com/reference/android/app/Activity.html
schlingel

32
onSaveInstanceStateතිරයේ දිශානතියේ වෙනස්වීම් හැරුණු විට එම කරුණ effectively ලදායී ලෙස පාහේ නිෂ් less ල වේ. අනෙක් සෑම අවස්ථාවකම පාහේ, ඔබට කිසි විටෙකත් එය මත විශ්වාසය තැබිය නොහැකි අතර ඔබේ UI තත්වය වෙනත් තැනක අතින් සුරැකීමට අවශ්‍ය වනු ඇත. නැතහොත් BACK බොත්තම් හැසිරීම ඉක්මවා යාමෙන් ඔබගේ යෙදුම විනාශ වීම වලක්වනු ඇත. ඔවුන් එය මේ ආකාරයෙන් ක්‍රියාත්මක කළේ ඇයිදැයි මට තේරෙන්නේ නැත. සම්පූර්ණයෙන්ම නොදැනුවත්ව. මෙම විශේෂිත ක්‍රමවේදය හැරෙන්නට ඔබට ඉතිරි කළ හැකි පද්ධතිය ඔබට ලබා දිය නොහැක.
චක්‍රිත්

12
UI තත්වය බණ්ඩලයට / සිට සුරැකීම / ප්‍රතිෂ් oring ාපනය කිරීම අයිඩී පවරා ඇති s සඳහා ස්වයංක්‍රීයව බලා ගන්නා බව සලකන්න . සිට ලේඛන: "පෙරනිමි ක්රියාත්මක කරනසේ විසින් ඔබ වෙනුවෙන් UI අනුව-උදාහරණයක් ප්රාන්තයේ බොහෝ බලාගන්නවා හැඳුනුම්පතක් ඇති බව රාව එක් එක් දැක්ම මත, සහ දැනට (දැක්ම යොමු නැවත වන සියලු පිළිබඳ හඳුනාගැනීමේ අංකය ද ඉතිරි කර පෙරනිමියෙන් ක්‍රියාත්මක කිරීමෙන් ) "ViewonSaveInstanceStateonSaveInstanceState()onRestoreInstanceState(Bundle)
විකී චිජ්වානි

434

මෙම savedInstanceStateඋදාහරණයක් වත්මන් සංචලනය හෝ තේරීම තොරතුරු සඳහා, ක්රියාකාරකම් පිළිබඳ වත්මන් උදාහරණයක් සම්බන්ධ රාජ්ය ඉතිරි ඇන්ඩ්රොයිඩ් විනාශ කරන හා ක්රියාකාරකම් මුහුණලා නම්, එය කලින් තිබූ ලෙස නැවත එන්න පුළුවන් ඒ නිසා ඒ සඳහා පමණි. onCreateසහ සඳහා ප්‍රලේඛනය බලන්නonSaveInstanceState

වඩා දිගු කාලයක් ජීවත් වීමට, SQLite දත්ත සමුදායක්, ගොනුවක් හෝ මනාපයන් භාවිතා කිරීම ගැන සලකා බලන්න. අඛණ්ඩ රාජ්‍යය සුරැකීම බලන්න .


3
සුරැකෙන්නේ කවදාද?
ට්‍රෝජන්.සොබොට්

6
පද්ධතිය ඔබගේ ක්‍රියාකාරිත්වයේ නව අවස්ථාවක් නිර්මාණය කරන විට saveInstanceState අහෝසි වන අතර එය ප්‍රතිස්ථාපනය කිරීමේදී ශුන්‍ය නොවේ.
ගේබ්‍රියෙල් කමාරා

7
... එමඟින් පද්ධතියේ නව ක්‍රියාකාරකමක් නිර්මාණය කිරීමට අවශ්‍ය වන්නේ කවදාද යන ප්‍රශ්නය මතු කරයි . යෙදුමකින් පිටවීමේ සමහර ක්‍රම මිටියක් සාදන්නේ නැත, එබැවින් නව අවස්ථාවක් නිර්මාණය කළ යුතුය. මූලික ගැටළුව මෙයයි; එයින් අදහස් කරන්නේ කෙනෙකුට මිටියේ පැවැත්ම මත විශ්වාසය තැබිය නොහැකි අතර, අඛණ්ඩව ගබඩා කිරීම සඳහා විකල්ප ක්‍රම කිහිපයක් කළ යුතු බවයි. OnSave / onRestoreInstanceState හි වාසිය නම් එය බොහෝ පද්ධති සම්පත් පරිභෝජනය නොකර පද්ධතියට හදිසියේ කළ හැකි යාන්ත්‍රණයක් වීමයි. එබැවින් එයට සහය දැක්වීම හොඳය, එසේම යෙදුමෙන් වඩාත් අලංකාර පිටවීම සඳහා නිරන්තර ගබඩා තබා ගන්න.
මෙවලම් සාදන්නා

415

Http://developer.android.com/reference/android/app/Activity.html හි ක්‍රියාකාරකම් තත්වයන් පිළිබඳ ලියකියවිලි වලට අනුව එය භාවිතා කිරීම සහ නිරන්තර දත්ත භාවිතා කිරීම ආරක්ෂිත නොවන බව සලකන්න .onSaveInstanceStateonRestoreInstanceState

ලේඛනයේ මෙසේ සඳහන් වේ ('ක්‍රියාකාරකම් ජීවන චක්‍රය' කොටසේ):

එය දිගටම පවතින දත්ත සුරැකීමට වැදගත් වන බව සටහන onPause()වෙනුවට onSaveInstanceState(Bundle) පසු ඇති ජීව callbacks කොටසක් නොවන අතර, එම නිසා එහි ලේඛන වල විස්තර කර ඇති ලෙස සෑම තත්වයක් ලෙස කළ නොහැකි වනු ඇත නිසා.

වෙනත් වචන වලින් කිවහොත්, අඛණ්ඩ දත්ත සඳහා ඔබගේ සුරැකීමේ / ප්‍රතිස්ථාපන කේතය තබන්න onPause()සහ onResume()!

සංස්කරණය කරන්න : වැඩිදුර පැහැදිලි කිරීම සඳහා, මෙන්න onSaveInstanceState()ප්‍රලේඛනය:

යම් ක්‍රියාවක් මරණයට පත්වීමට පෙර මෙම ක්‍රමය හඳුන්වනු ලබන අතර එමඟින් අනාගතයේ යම් කාලයක් නැවත පැමිණෙන විට එය යථා තත්වයට පත් කළ හැකිය. නිදසුනක් ලෙස, ක්‍රියාකාරකම් A ඉදිරිපිට දියත් කර ඇත්නම් සහ යම් අවස්ථාවක දී සම්පත් නැවත ලබා ගැනීම සඳහා ක්‍රියාකාරකම් A මිය ගියහොත්, ක්‍රියාකාරකම් A මඟින් මෙම ක්‍රමය හරහා එහි පරිශීලක අතුරුමුහුණතේ වත්මන් තත්වය සුරැකීමට අවස්ථාවක් ලැබෙනු ඇත, එවිට පරිශීලකයා නැවත පැමිණෙන විට A ක්‍රියාකාරකම් සඳහා, පරිශීලක අතුරුමුහුණතේ තත්වය onCreate(Bundle)හෝ හරහා ප්‍රතිස්ථාපනය කළ හැකිය onRestoreInstanceState(Bundle).


55
නිට්පික් කිරීමට: එය අනාරක්ෂිත නොවේ. මෙය රඳා පවතින්නේ ඔබට සංරක්ෂණය කිරීමට අවශ්‍ය දේ සහ කොපමණ කාලයක් සඳහාද, බර්නාඩ්ගේ මුල් ප්‍රශ්නයේදී එය සම්පූර්ණයෙන්ම පැහැදිලි නැත. වර්තමාන UI තත්වය ආරක්ෂා කිරීම සඳහා InstanceState පරිපූර්ණයි (දත්ත පාලනයට ඇතුළත් කර ඇත, ලැයිස්තු වල වත්මන් ස්ථාන සහ යනාදිය), නමුත් විරාමය / නැවත ආරම්භ කිරීම දිගු කාලීනව අඛණ්ඩව ගබඩා කිරීම සඳහා ඇති එකම හැකියාවයි.
පොන්ටස් ගග්

30
මෙය පහත් කළ යුතුය. (සුරකින්න | ප්‍රතිස්ථාපනය කරන්න) ජීවන චක්‍රීය ක්‍රම වැනි InstanceState හි භාවිතා කිරීම ආරක්ෂිත නොවේ (එනම් තත්වය සුරැකීමට / යථා තත්වයට පත් කිරීමට වඩා වෙනත් කිසිවක් ඔවුන් තුළ කරන්න). තත්වය සුරැකීමට / ප්‍රතිෂ් oring ාපනය කිරීමට ඒවා ඉතා හොඳයි. එසේම, onPause සහ onResume හි තත්වය සුරැකීමට / ප්‍රතිස්ථාපනය කිරීමට ඔබට අවශ්‍ය වන්නේ කෙසේද? ඔබට භාවිතා කළ හැකි එම ක්‍රමවේදයන් තුළ ඔබට මිටි නොලැබෙන අතර, ඒ නිසා මෝඩ වන දත්ත සමුදායන්, ලිපිගොනු ආදියෙහි වෙනත් රාජ්‍ය ඉතිරිකිරීම් භාවිතා කිරීමට ඔබට සිදුවේ.
ෆීලික්ස්

141
අවම වශයෙන් ඔහු ලියකියවිලි කියවීමට උත්සාහ කළත්, අපි හිතන්නේ අපි දැනුවත්ව ප්‍රජාවක් ගොඩනැගීම සඳහා සහ ඡන්දය ප්‍රකාශ නොකිරීමට එකිනෙකාට උදව් කිරීම සඳහා අපි මෙහි සිටිමු. ඒ නිසා උත්සාහය සඳහා 1 ක් ඡන්දය දෙන්න, මම ඔබෙන් ඉල්ලා සිටින්නේ ඡන්දය පාවිච්චි නොකරන ලෙසට නොව ඡන්දය ප්‍රකාශ නොකරන ලෙසයි .... මෙම පුද්ගලයා ලියකියවිලි හරහා යෑමට කැමති කෙනෙකුට ඇති වියවුල්සහගත බව ඉවත් කරයි. 1 ඡන්දය :)
AZ_

21
මම හිතන්නේ නැහැ මේ පිළිතුර පහත් කොට සැලකීමට සුදුසුයි කියා. අවම වශයෙන් ඔහු පිළිතුරු දීමට උත්සාහයක් ගත් අතර ඩොකෝ වෙතින් කොටසක් උපුටා දැක්වීය.
GSree

34
මෙම පිළිතුර නියත වශයෙන්ම නිවැරදි වන අතර යූපී ඡන්දය ලැබීමට සුදුසුය. එය නොදකින අය සඳහා ප්‍රාන්ත අතර වෙනස පැහැදිලි කිරීමට මට ඉඩ දෙන්න. ලැයිස්තු දර්ශනයක පෙන්වන ලැයිස්තුවකට එකතු කරන ලද වාර්තා වැනි, තෝරාගත් ගුවන්විදුලි බොත්තම් සහ ආදාන ක්ෂේත්‍රයේ සමහර පෙළ වැනි GUI තත්වයක් දත්ත තත්වයට වඩා බෙහෙවින් අඩු ය. දෙවැන්න onPause හි දත්ත ගබඩාවට ගබඩා කළ යුතුය, මන්ද එය එකම සහතික කළ ඇමතුමයි. ඒ වෙනුවට ඔබ එය onSaveInstanceState හි තැබුවහොත්, එය නොකියන්නේ නම් දත්ත නැතිවීමේ අවදානමක් ඇත. නමුත් රේඩියෝ බොත්තම් තේරීම එකම හේතුවක් නිසා සුරැකෙන්නේ නැත්නම් - එය ලොකු දෙයක් නොවේ.
ජේබීඑම්

206

මගේ සගයා රාජ්ය තොරතුරු ගබඩා කරන ආකාරය, ක්රියාකාරකම් ජිවන චක්රය සහ රාජ්ය තොරතුරු මත පැහැදිලි කිරීම් ඇතුළු Android උපාංග මත අයදුම් රාජ්ය පැහැදිලි ලිපියක් ලියූ අතර, රාජ්ය ඉතිරි කිරීමට Bundleහා SharedPreferencesහා මෙතන දිහා .

ලිපිය ප්රවේශයන් තුනක් ආවරණය කරයි:

යෙදුම් ජීවිත කාලය සඳහා (එනම් තාවකාලිකව) දේශීය විචල්‍ය / යූඅයි පාලන දත්ත නිදර්ශන රාජ්‍ය මිටියක් භාවිතා කර ගබඩා කරන්න

[Code sample  Store state in state bundle]
@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
  // Store UI state to the savedInstanceState.
  // This bundle will be passed to onCreate on next call.  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  savedInstanceState.putString(“Name”, strName);
  savedInstanceState.putString(“Email”, strEmail);
  savedInstanceState.putBoolean(“TandC”, blnTandC);

  super.onSaveInstanceState(savedInstanceState);
}

හවුල් මනාපයන් භාවිතා කරමින් යෙදුම් අවස්ථා අතර (එනම් ස්ථිරවම) දේශීය විචල්‍ය / UI පාලන දත්ත ගබඩා කරන්න

[Code sample  store state in SharedPreferences]
@Override
protected void onPause()
{
  super.onPause();

  // Store values between instances here
  SharedPreferences preferences = getPreferences(MODE_PRIVATE);
  SharedPreferences.Editor editor = preferences.edit();  // Put the values from the UI
  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  editor.putString(“Name”, strName); // value to store
  editor.putString(“Email”, strEmail); // value to store
  editor.putBoolean(“TandC”, blnTandC); // value to store
  // Commit to storage
  editor.commit();
}

වින්‍යාසගත නොකල නිදසුනක් භාවිතා කරමින් යෙදුම් ජීවිත කාලය තුළ ක්‍රියාකාරකම් අතර වස්තු සිද්ධීන් මතකයේ තබා ගැනීම

[Code sample  store object instance]
private cMyClassType moInstanceOfAClass; // Store the instance of an object
@Override
public Object onRetainNonConfigurationInstance()
{
  if (moInstanceOfAClass != null) // Check that the object exists
      return(moInstanceOfAClass);
  return super.onRetainNonConfigurationInstance();
}

3
@ මාටින්බෙල්චර්-ඊගෝ ලිපියෙහි SharedPreferences හි දත්ත ගැන පවසන්නේ "මෙම දත්ත උපාංගයේ දත්ත ගබඩාවට ලියා ඇත .." දත්ත පද්ධතියේ යෙදුම් නාමාවලියෙහි ගොනුවක ගබඩා කර ඇති බව මම විශ්වාස කරමි.
ටොම්

2
ShaTom SharefPrefs දත්ත xml ගොනුවට ලියා ඇත. Xml යනු දත්ත සමුදායක්ද? මම කියන්නේ එය;)
මැකීජ්ගෝර්ස්කි

148

මෙය ඇන්ඩ්‍රොයිඩ් සංවර්ධනයේ සම්භාව්‍ය 'ගොචා' ය. මෙහි ගැටළු දෙකක් තිබේ:

  • සියුම් ඇන්ඩ්‍රොයිඩ් රාමු දෝෂයක් ඇත, එය සංවර්ධනයේදී යෙදුම් තොග කළමනාකරණය බෙහෙවින් සංකීර්ණ කරයි, අවම වශයෙන් පැරණි අනුවාදයන් මත (එය සවි කර ඇත්දැයි / කවදාද / කෙසේද යන්න සම්පූර්ණයෙන්ම විශ්වාස නැත). මම මෙම දෝෂය පහතින් සාකච්ඡා කරමි.
  • මෙම ගැටළුව කළමනාකරණය කිරීම සඳහා 'සාමාන්‍ය' හෝ අපේක්ෂිත ක්‍රමය, onPause / onResume සහ onSaveInstanceState / onRestoreInstanceState හි ද්විත්ව භාවයට වඩා සංකීර්ණ ය.

මේ සියලු නූල් හරහා සැරිසරමින්, සංවර්ධකයින් බොහෝ විට මෙම වෙනස් කාරණා දෙක ගැන එකවර කතා කරයි යැයි මම සැක කරමි ... එබැවින් "මෙය මට වැඩ කරන්නේ නැත" යන සියලු ව්‍යාකූලතා සහ වාර්තා.

පළමුව, 'අපේක්ෂිත' හැසිරීම පැහැදිලි කිරීම සඳහා: onSaveInstance සහ onRestoreInstance බිඳෙන සුළු වන අතර එය අස්ථිර තත්වයට පමණි. අපේක්ෂිත භාවිතය (afaict) යනු දුරකථනය භ්‍රමණය වන විට ක්‍රියාකාරකම් විනෝදය හැසිරවීමයි (දිශානතිය වෙනස් කිරීම). වෙනත් වචන වලින් කිවහොත්, අපේක්ෂිත භාවිතය වන්නේ ඔබේ ක්‍රියාකාරකම තාර්කිකව 'ඉහළින්' ඇති නමුත් පද්ධතිය විසින් නැවත ස්ථාපනය කළ යුතුය. සුරකින ලද බණ්ඩලය ක්‍රියාවලියෙන් / මතකයෙන් / ජීසී වලින් පිටත නොපවතින බැවින් ඔබේ ක්‍රියාකාරකම් පසුබිමට ගියහොත් ඔබට මෙය මත විශ්වාසය තැබිය නොහැක. ඔව්, සමහර විට ඔබේ ක්‍රියාකාරකම් මතකය එහි පසුබිම කරා ගමන් කර GC වලින් බේරෙනු ඇත, නමුත් මෙය විශ්වාසදායක නොවේ (එය අනාවැකි කිව නොහැක).

එබැවින් ඔබේ යෙදුමේ 'දියත් කිරීම්' අතර අර්ථවත් 'පරිශීලක ප්‍රගතියක්' හෝ තත්වයක් පවතින තත්වයක් ඔබට තිබේ නම්, මඟ පෙන්වීම වන්නේ onPause සහ onResume භාවිතා කිරීමයි. ඔබ විසින්ම අඛණ්ඩ වෙළඳසැලක් තෝරාගෙන සකස් කළ යුතුය.

නමුත් - මේ සියල්ල අවුල් කරන ඉතා ව්‍යාකූල දෝෂයකි. විස්තර මෙහි ඇත:

http://code.google.com/p/android/issues/detail?id=2373

http://code.google.com/p/android/issues/detail?id=5277

මූලික වශයෙන්, ඔබගේ යෙදුම සිංගල් ටැස්ක් ධජය සමඟ දියත් කර, පසුව ඔබ එය මුල් තිරයේ හෝ දියත් කිරීමේ මෙනුවෙන් දියත් කළහොත්, පසුව එන ආයාචනය මඟින් නව කාර්යයක් නිර්මාණය වනු ඇත ... ඔබේ යෙදුමේ වෙනස් අවස්ථා දෙකක් ඔබට effectively ලදායී වනු ඇත එකම තොගයේ වාසය කිරීම ... ඉතා වේගයෙන් අමුතු දෙයක් බවට පත්වේ. සංවර්ධනයේදී ඔබ ඔබේ යෙදුම දියත් කරන විට මෙය සිදු වන බව පෙනේ (එනම් එක්ලිප්ස් හෝ ඉන්ටෙලිජ් වෙතින්), එබැවින් සංවර්ධකයින් මේ සඳහා බොහෝ දුරට දිව යයි. සමහර යෙදුම් ගබඩා යාවත්කාලීන කිරීමේ යාන්ත්‍රණයන් හරහාද (එබැවින් එය ඔබගේ පරිශීලකයින්ටද බලපායි).

මගේ ප්‍රධාන ගැටළුව මෙම දෝෂය මිස අපේක්ෂිත රාමු හැසිරීම නොවන බව වටහා ගැනීමට පෙර මම මෙම නූල් හරහා පැය ගණනක් සටන් කළෙමි. විශිෂ්ට ලිවීමක් සහවැඩ කිරීම (යාවත්කාලීන කිරීම: පහත බලන්න) මෙම පිළිතුරෙහි ac කකියුලා පරිශීලකයාගෙන් බව පෙනේ:

නිවසේ යතුරු මාධ්‍ය හැසිරීම

2013 ජුනි යාවත්කාලීන කරන්න : මාස ගණනාවකට පසු, මම අවසානයේ 'නිවැරදි' විසඳුම සොයා ගතිමි. ආරම්භක ඇප් කොඩි ඔබ විසින්ම කළමනාකරණය කිරීමට ඔබට අවශ්‍ය නැත, ඔබට මෙය රාමුවෙන් හඳුනාගෙන නිසි පරිදි ඇප ලබා ගත හැකිය. මම මෙය මගේ LauncherActivity.onCreate ආරම්භයේදී භාවිතා කරමි.

if (!isTaskRoot()) {
    Intent intent = getIntent();
    String action = intent.getAction();
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {
        finish();
        return;
    }
}

87

onSaveInstanceStateපද්ධතියට මතකය අවශ්‍ය වූ විට සහ යෙදුමක් විනාශ කරන විට එය හැඳින්වේ. පරිශීලකයා යෙදුම වසා දැමූ විට එය නොකියයි. ඒ නිසා මම හිතන්නේ අයදුම් රාජ්ය ද සුරැකිය යුතුය onPauseඒ වගේ සමහර අනවරත සංචිත සුරැකිය යුතු PreferencesහෝSqlite


37
කණගාටුයි, එය එතරම් නිවැරදි නැත. ක්‍රියාකාරකම නැවත සෑදීමට පෙර onSaveInstanceState අමතනු ලැබේ. එනම් පරිශීලකයා උපාංගය භ්‍රමණය වන සෑම අවස්ථාවකම. එය අස්ථිර දර්ශන තත්වයන් ගබඩා කිරීම සඳහා අදහස් කෙරේ. ඇන්ඩ්‍රොයිඩ් විසින් යෙදුම වසා දැමීමට බල කරන විට, onSaveInstanceState ඇත්ත වශයෙන්ම හැඳින්වෙන්නේ නැත (වැදගත් යෙදුම් දත්ත ගබඩා කිරීම සඳහා එය අනාරක්ෂිත වන්නේ එබැවිනි). onPause, කෙසේ වෙතත් ක්‍රියාකාරකම මරණයට පත්වීමට පෙර කැඳවීමට සහතික වී ඇත, එබැවින් එය මනාපයන් හෝ Squlite හි ස්ථිර තොරතුරු ගබඩා කිරීමට භාවිතා කළ යුතුය. නිවැරදි පිළිතුර, වැරදි හේතු.
moveaway00

74

මෙම ක්‍රම දෙකම ප්‍රයෝජනවත් සහ වලංගු වන අතර දෙකම විවිධ අවස්ථා සඳහා වඩාත් සුදුසු වේ:

  1. පරිශීලකයා යෙදුම අවසන් කර පසු දිනකදී එය නැවත විවෘත කරයි, නමුත් යෙදුමට අවසාන සැසියේ සිට දත්ත නැවත පූරණය කිරීමට අවශ්‍ය වේ - මේ සඳහා SQLite භාවිතා කිරීම වැනි අඛණ්ඩ ගබඩා ප්‍රවේශයක් අවශ්‍ය වේ.
  2. පරිශීලක යෙදුම මාරු පසුව නැවත මුල් එන ඔවුන් නතර කළ එසවීමට අවශ්ය - මිටියක් දත්ත (එවැනි ඉල්ලීමක් රාජ්ය දත්ත ලෙස) සුරැකීමට සහ යථා onSaveInstanceState()හා onRestoreInstanceState()සාමාන්යයෙන් ප්රමාණවත් වේ.

ඔබ දිගටම පවතින ආකාරයෙන් රාජ්ය දත්ත සුරැකීමට නම්, එය තුළ Reloaded කළ හැකි onResume()හෝ onCreate()(ඕනෑම ජීව ඇමතුමක් හෝ ඇත්තටම). මෙය අපේක්ෂිත හැසිරීම විය හැකිය හෝ නොවිය හැකිය. ඔබ එය මිටියක් තුළ ගබඩා කරන්නේ නම් InstanceState, එය අස්ථිර වන අතර එකම පරිශීලක 'සැසිය' තුළ භාවිතා කිරීම සඳහා දත්ත ගබඩා කිරීම සඳහා පමණක් සුදුසු වේ (මම සැසිය යන යෙදුම ලිහිල්ව භාවිතා කරමි) නමුත් 'සැසි' අතර නොවේ.

සෑම ප්‍රවේශයක්ම මෙන් එක් ප්‍රවේශයක් අනෙකට වඩා හොඳ බව නොවේ, ඔබට අවශ්‍ය හැසිරීම තේරුම් ගැනීම සහ වඩාත් සුදුසු ප්‍රවේශය තෝරා ගැනීම වැදගත් ය.


70

මා සිතන පරිදි රාජ්‍යය සුරැකීම හොඳම දෙයකි. ඔබට අඛණ්ඩ දත්ත සුරැකීමට අවශ්‍ය නම්, SQLite දත්ත සමුදායක් භාවිතා කරන්න . ඇන්ඩ්‍රොයිඩ් එය SOOO පහසු කරයි.

මේ වගේ දෙයක්:

import java.util.Date;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class dataHelper {

    private static final String DATABASE_NAME = "autoMate.db";
    private static final int DATABASE_VERSION = 1;

    private Context context;
    private SQLiteDatabase db;
    private OpenHelper oh ;

    public dataHelper(Context context) {
        this.context = context;
        this.oh = new OpenHelper(this.context);
        this.db = oh.getWritableDatabase();
    }

    public void close() {
        db.close();
        oh.close();
        db = null;
        oh = null;
        SQLiteDatabase.releaseMemory();
    }


    public void setCode(String codeName, Object codeValue, String codeDataType) {
        Cursor codeRow = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        String cv = "" ;

        if (codeDataType.toLowerCase().trim().equals("long") == true){
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            cv = String.valueOf(((Date)codeValue).getTime());
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            String.valueOf(codeValue);
        }
        else
        {
            cv = String.valueOf(codeValue);
        }

        if(codeRow.getCount() > 0) //exists-- update
        {
            db.execSQL("update code set codeValue = '" + cv +
                "' where codeName = '" + codeName + "'");
        }
        else // does not exist, insert
        {
            db.execSQL("INSERT INTO code (codeName, codeValue, codeDataType) VALUES(" +
                    "'" + codeName + "'," +
                    "'" + cv + "'," +
                    "'" + codeDataType + "')" );
        }
    }

    public Object getCode(String codeName, Object defaultValue){

        //Check to see if it already exists
        String codeValue = "";
        String codeDataType = "";
        boolean found = false;
        Cursor codeRow  = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        if (codeRow.moveToFirst())
        {
            codeValue = codeRow.getString(codeRow.getColumnIndex("codeValue"));
            codeDataType = codeRow.getString(codeRow.getColumnIndex("codeDataType"));
            found = true;
        }

        if (found == false)
        {
            return defaultValue;
        }
        else if (codeDataType.toLowerCase().trim().equals("long") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (long)0;
            }
            return Long.parseLong(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (int)0;
            }
            return Integer.parseInt(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            if (codeValue.equals("") == true)
            {
                return null;
            }
            return new Date(Long.parseLong(codeValue));
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            if (codeValue.equals("") == true)
            {
                return false;
            }
            return Boolean.parseBoolean(codeValue);
        }
        else
        {
            return (String)codeValue;
        }
    }


    private static class OpenHelper extends SQLiteOpenHelper {

        OpenHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE IF  NOT EXISTS code" +
            "(id INTEGER PRIMARY KEY, codeName TEXT, codeValue TEXT, codeDataType TEXT)");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
}

ඊට පසු සරල ඇමතුමක්

dataHelper dh = new dataHelper(getBaseContext());
String status = (String) dh.getCode("appState", "safetyDisabled");
Date serviceStart = (Date) dh.getCode("serviceStartTime", null);
dh.close();
dh = null;

9
SQLite දත්ත ගබඩාවක් පූරණය කිරීමට බොහෝ කාලයක් ගත වන හෙයින්, මෙය යෙදුමේ UI පරිශීලකයාට පෙන්වීමේ තීරණාත්මක මාවතේ ඇති බව සලකයි. මම එය ඇත්ත වශයෙන්ම කාලානුරූපී කර නැත, එබැවින් නිවැරදි කිරීම ගැන මම සතුටු වෙමි, නමුත් නිසැකවම දත්ත සමුදා ගොනුවක් පැටවීම සහ විවෘත කිරීම වේගවත් නොවේද?
ටොම්

5
නවකයකුට ඔවුන්ගේ යෙදුමට කපා ඇලවිය හැකි විසඳුමක් ලබා දීම ගැන ඔබට බොහෝම ස්තූතියි! Om ටොම් වේගය වැඩි වන විට යුගල 1000 ක් ගබඩා කිරීමට තත්පර හතක් පමණ ගත වේ, නමුත් ඔබට එය අසින්ක් කාර්යයකින් කළ හැකිය. කෙසේ වෙතත්, ඔබ අවසානයේ {cursor.close () add එකතු කළ යුතුය, නැතහොත් මෙය සිදු කරන විට එය මතක කාන්දු වීමෙන් බිඳ වැටෙනු ඇත.
නූමනන්

3
මට මෙය හමු වූ අතර එය පිළිවෙලට පෙනෙන අතර ගූගල් ග්ලාස් හි මෙය භාවිතා කිරීමට උත්සාහ කිරීමට මම පසුබට වෙමි, මෙය මම මෑතකදී / සමඟ වැඩ කරන උපාංගයයි.
ස්ටීවන් ටෙට්‍රෝල්ට්

61

මම හිතන්නේ මම පිළිතුර සොයාගත්තා. මා කළ දේ සරල වචන වලින් කියන්නම්:

මට ක්‍රියාකාරකම් 2 ක් ඇති බව සිතමු, ක්‍රියාකාරකම් 1 සහ ක්‍රියාකාරකම් 2 සහ මම ක්‍රියාකාරකම් 1 සිට ක්‍රියාකාරකම් 2 දක්වා ගමන් කරමි (මම ක්‍රියාකාරකම් 2 හි සමහර වැඩ කර ඇත) සහ ක්‍රියාකාරකම් 1 හි බොත්තමක් ක්ලික් කිරීමෙන් නැවත ක්‍රියාකාරකම් 1 වෙත යන්න. දැන් මෙම අවස්ථාවෙහිදී මට නැවත ක්‍රියාකාරකම 2 වෙත යාමට අවශ්‍ය වූ අතර මම අවසන් වරට ක්‍රියාකාරකම 2 අතහැර ගිය විට මගේ ක්‍රියාකාරකම් 2 එකම තත්වයේ දැකීමට අවශ්‍යය.

ඉහත සිදුවීම සඳහා මා විසින් කර ඇති දෙය නම්, මැනිෆෙස්ටයේ දී මම මේ වගේ වෙනස්කම් කිහිපයක් කළෙමි:

<activity android:name=".activity2"
          android:alwaysRetainTaskState="true"      
          android:launchMode="singleInstance">
</activity>

බොත්තම ක්ලික් කිරීමේ සිද්ධියේ ක්‍රියාකාරකම් 1 හි මම මේ ආකාරයට කර ඇත:

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.setClassName(this,"com.mainscreen.activity2");
startActivity(intent);

ක්‍රියාකාරකම් 2 මත බොත්තම ක්ලික් කිරීමේ සිද්ධියේදී මම මේ ආකාරයට කර ඇත:

Intent intent=new Intent();
intent.setClassName(this,"com.mainscreen.activity1");
startActivity(intent);

දැන් සිදුවන්නේ කුමක් ද යන්න නම්, ක්‍රියාකාරකම් 2 හි අප විසින් සිදු කරන ලද වෙනස්කම් කුමක් වුවත් නැති නොවනු ඇති අතර, ක්‍රියාකාරකම් 2 අප කලින් හැර ගිය තත්වයේම දැක ගත හැකිය.

මම විශ්වාස කරන්නේ මෙය පිළිතුර වන අතර මෙය මට හොඳින් ක්‍රියාත්මක වේ. මම වැරදියි නම් මාව නිවැරදි කරන්න.


2
agbagusflyer රැකවරණය වඩාත් නිශ්චිත විය යුතුද ??? ඔබේ අදහස ප්‍රයෝජනවත් නොවන අතර ඒ මත පදනම්ව කිසිවෙකුට ඔබට උදව් කළ නොහැක.
ස්ටීවන් ටෙට්‍රෝල්ට්

2
මෙය වෙනස් තත්වයකට පිළිතුරකි: එකම යෙදුම තුළ ක්‍රියාකාරකම් දෙකක්. OP යනු යෙදුමෙන් ඉවත් වීමයි (උදා: මුල් පිටුව බොත්තම, හෝ වෙනත් යෙදුමකට මාරුවීමට වෙනත් ක්‍රම).
මෙවලම් සාදන්නා

44

onSaveInstanceState()අස්ථිර දත්ත සඳහා ( onCreate()/ තුළ ප්‍රතිෂ් ored ාපනය කරන ලදි onRestoreInstanceState()), onPause()අඛණ්ඩ දත්ත සඳහා (ප්‍රතිස්ථාපනය කරන ලදි onResume()). Android තාක්ෂණික සම්පත් වලින්:

ක්‍රියාකාරකම නවත්වන්නේ නම් එය නැවත ආරම්භ කිරීමට පෙර මරා දැමිය හැකි නම් onSaveInstanceState () ඇන්ඩ්‍රොයිඩ් විසින් අමතනු ලැබේ! මෙයින් අදහස් කරන්නේ ක්‍රියාකාරකම නැවත ආරම්භ කරන විට එම තත්වයටම නැවත ආරම්භ කිරීමට අවශ්‍ය ඕනෑම රාජ්‍යයක් ගබඩා කළ යුතු බවයි. එය onCreate () ක්‍රමයට ප්‍රතිවිරුද්ධ පාර්ශවය වන අතර ඇත්ත වශයෙන්ම onCreate () වෙත ලබා දුන් saveInstanceState බණ්ඩලය onSaveInstanceState () ක්‍රමයේදී ඔබ OutState ලෙස ගොඩනඟන ලද එකම මිටි වේ.

onPause () සහ onResume ()අනුපූරක ක්‍රම වේ. onPause () සැමවිටම හැඳින්වෙන්නේ ක්‍රියාකාරකම අවසන් වූ විටය, අප එය උසිගැන්වුවද (නිමාවකින් () උදාහරණයක් ලෙස). වත්මන් සටහන නැවත දත්ත ගබඩාවට සුරැකීමට අපි මෙය භාවිතා කරමු. හොඳ පුරුද්දක් වන්නේ onPause () අතරතුර මුදා හැරිය හැකි ඕනෑම සම්පත් නිදහස් කිරීම, උදාසීන තත්වයේ සිටින විට අඩු සම්පත් ප්‍රමාණයක් ලබා ගැනීමයි.


40

onSaveInstanceState()ක්‍රියාකාරකම පසුබිමට යන විට සැබවින්ම හැඳින්වේ.

ලියකියවිලි වලින් උපුටා ගැනීම: "යම් ක්‍රියාවක් මරණයට පත්වීමට පෙර මෙම ක්‍රමය හැඳින්වෙන්නේ අනාගතයේ යම් කාලයක් තුළ එය නැවත පැමිණෙන විට එහි තත්වය යථා තත්වයට පත් කළ හැකි බැවිනි." මූලාශ්රය


37

උදව් කිරීමට මම පහත දැක්වෙන ගිනි උදුනක් අඩු interfaceහා classකියවීමට ලිවීමට / වෙත Bundleඋදාහරණයක් රාජ්ය ඉතිරි සඳහා.


පළමුව, ඔබේ නිදර්ශන විචල්‍යයන් විවරණය කිරීමට භාවිතා කරන අතුරු මුහුණතක් සාදන්න:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
        ElementType.FIELD
})
public @interface SaveInstance {

}

ඉන්පසු, මිටියට අගයන් සුරැකීමට පරාවර්තනය භාවිතා කරන පන්තියක් සාදන්න:

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

import java.io.Serializable;
import java.lang.reflect.Field;

/**
 * Save and load fields to/from a {@link Bundle}. All fields should be annotated with {@link
 * SaveInstance}.</p>
 */
public class Icicle {

    private static final String TAG = "Icicle";

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #load(Bundle, Object)
     */
    public static void save(Bundle outState, Object classInstance) {
        save(outState, classInstance, classInstance.getClass());
    }

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #load(Bundle, Object, Class)
     */
    public static void save(Bundle outState, Object classInstance, Class<?> baseClass) {
        if (outState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    field.setAccessible(true);
                    String key = className + "#" + field.getName();
                    try {
                        Object value = field.get(classInstance);
                        if (value instanceof Parcelable) {
                            outState.putParcelable(key, (Parcelable) value);
                        } else if (value instanceof Serializable) {
                            outState.putSerializable(key, (Serializable) value);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not added to the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #save(Bundle, Object)
     */
    public static void load(Bundle savedInstanceState, Object classInstance) {
        load(savedInstanceState, classInstance, classInstance.getClass());
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #save(Bundle, Object, Class)
     */
    public static void load(Bundle savedInstanceState, Object classInstance, Class<?> baseClass) {
        if (savedInstanceState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    String key = className + "#" + field.getName();
                    field.setAccessible(true);
                    try {
                        Object fieldVal = savedInstanceState.get(key);
                        if (fieldVal != null) {
                            field.set(classInstance, fieldVal);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not retrieved from the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

}

උදාහරණ භාවිතය:

public class MainActivity extends Activity {

    @SaveInstance
    private String foo;

    @SaveInstance
    private int bar;

    @SaveInstance
    private Intent baz;

    @SaveInstance
    private boolean qux;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Icicle.load(savedInstanceState, this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Icicle.save(outState, this);
    }

}

සටහන: මෙම කේතය අනුවර්තනය කරන ලද්දේ MIT බලපත්‍රය යටතේ බලපත්‍ර ලබා ඇති AndroidAutowire නම් පුස්තකාල ව්‍යාපෘතියකිනි .


34

මේ අතර මම පොදුවේ වැඩි ප්‍රයෝජනයක් නැත

Bundle savedInstanceState & Co

ජීවන චක්‍රය බොහෝ ක්‍රියාකාරකම් සඳහා ඉතා සංකීර්ණ වන අතර අවශ්‍ය නොවේ.

ගූගල් විසින්ම කියා සිටින්නේ එය විශ්වාසදායක නොවන බවයි.

මගේ ක්‍රමය මනාපයන්හි ඕනෑම වෙනස්කමක් වහාම සුරැකීමයි:

 SharedPreferences p;
 p.edit().put(..).commit()

යම් ආකාරයකින් SharedPreferences බණ්ඩල්ස් මෙන් ක්‍රියා කරයි. ස්වාභාවිකවම සහ මුලදී එවැනි අගයන් මනාපයන්ගෙන් කියවිය යුතුය.

සංකීර්ණ දත්ත සම්බන්ධයෙන් ඔබට මනාපයන් භාවිතා කිරීම වෙනුවට SQLite භාවිතා කළ හැකිය.

මෙම සංකල්පය ක්‍රියාවට නංවන විට, ක්‍රියාකාරකම අවසන් වරට සුරකින ලද තත්වය භාවිතා කරයි, එය අතර නැවත පණගැන්වීම් සහිත ආරම්භක විවෘතද යන්න හෝ පසුපස සිරස් නිසා නැවත විවෘත කිරීමද යන්න නොසලකා.


31

මුල් ප්‍රශ්නයට කෙලින්ම පිළිතුරු දීමට. ඔබගේ ක්‍රියාකාරකම කිසි විටෙකත් ප්‍රතිනිර්මාණය නොවන නිසා saveInstancestate අහෝසි වේ.

ඔබගේ ක්‍රියාකාරකම නැවත නිර්මාණය වන්නේ රාජ්‍ය මිටියක් සමඟ පමණි:

  • නව ක්‍රියාකාරකම් නිදසුනක් නිර්මාණය කිරීමට අවශ්‍ය විය හැකි දිශානතිය හෝ දුරකථන භාෂාව වෙනස් කිරීම වැනි වින්‍යාස වෙනස් කිරීම්.
  • මෙහෙයුම් පද්ධතිය ක්‍රියාකාරකම් විනාශ කිරීමෙන් පසු ඔබ පසුබිමෙන් යෙදුම වෙත නැවත පැමිණේ.

මතක පීඩනය යටතේ හෝ දීර් background කාලයක් පසුබිමේ සිටීමෙන් පසුව ඇන්ඩ්‍රොයිඩ් පසුබිම් ක්‍රියාකාරකම් විනාශ කරයි.

ඔබගේ ආයුබෝවන් ලෝක උදාහරණය පරික්ෂා කිරීමේදී පිටත්ව ගොස් ක්‍රියාකාරකම වෙත ආපසු යාමට ක්‍රම කිහිපයක් තිබේ.

  • ඔබ පසුපස බොත්තම එබූ විට ක්‍රියාකාරකම අවසන්. යෙදුම නැවත දියත් කිරීම නවතම අවස්ථාවකි. ඔබ කිසිසේත්ම පසුබිමෙන් ආරම්භ නොවේ.
  • ඔබ මුල් බොත්තම එබූ විට හෝ කාර්ය ස්විචරය භාවිතා කරන විට ක්‍රියාකාරකම පසුබිමට යයි. නැවත යෙදුමට සැරිසැරීමේදී ක්‍රියේට් කැඳවනු ලබන්නේ ක්‍රියාකාරකම් විනාශ කිරීමට සිදුවුවහොත් පමණි.

බොහෝ අවස්ථාවන්හිදී ඔබ ගෙදර එබීමෙන් පසුව යෙදුම නැවත දියත් කරන්නේ නම් ක්‍රියාකාරකම නැවත නිර්මාණය කිරීම අවශ්‍ය නොවේ. එය දැනටමත් මතකයේ පවතින බැවින් onCreate () කැඳවනු නොලැබේ.

සැකසීම් -> සංවර්ධක විකල්පයන් යටතේ "ක්‍රියාකාරකම් තබා නොගන්න" යනුවෙන් විකල්පයක් ඇත. එය සක්‍රිය කළ විට ඇන්ඩ්‍රොයිඩ් සැමවිටම ක්‍රියාකාරකම් විනාශ කරන අතර ඒවා පසුබිම් වූ විට ඒවා ප්‍රතිනිර්මාණය කරයි. සංවර්ධනය කිරීමේදී සක්‍රීයව තැබීමට මෙය හොඳ විකල්පයක් වන අතර එය නරකම අවස්ථාව අනුකරණය කරයි. (ඔබගේ ක්‍රියාකාරකම් නිතරම ප්‍රතිචක්‍රීකරණය කරන අඩු මතක උපාංගයක්).

අනෙක් පිළිතුරු ඉතා වැදගත් වන්නේ ඔවුන් ඔබට රාජ්ය ගබඩා කිරීම සඳහා නිවැරදි ක්රම උගන්වන නමුත් ඔබේ කේතය ඔබ අපේක්ෂා කළ ආකාරයට ක්රියා නොකරන්නේ මන්දැයි ඔවුන් සැබවින්ම පිළිතුරු දුන් බවක් මට දැනුනේ නැත.


28

මෙම onSaveInstanceState(bundle)සහ onRestoreInstanceState(bundle)ක්රම තිරය (දිශානතිය වෙනස් කිරීම) භ්රමණය දත්ත හුදෙක් භෞතික සාධක සඳහා ප්රයෝජනවත් වේ.
ඔවුන් සිට (අයදුම්පත් අතර මාරු වන අතර පවා හොඳ onSaveInstanceState()ක්රමය ලෙස හැඳින්වේ නමුත් onCreate(bundle)සහ onRestoreInstanceState(bundle)යලි නැත.
වැඩි අඛන්ඩතාවය භාවිතය සඳහා මනාප ගත්තා. මේ ලිපිය කියවන්න


2
ඔබේ නඩුව onCreateසහ onRestoreInstanceStateඑම නිසා හැඳින්වේ නොවන කරමින් Activityසියලු දී ඔබ යෙදුම් මාරු විට විනාශ නොවන අතර, එම නිසා කිසිම දෙයක් නැවත ගැනීමේ අවශ්යතාවයක් නැත. onSaveInstanceStateක්‍රියාකාරකම පසුව විනාශ වූ විට ඇන්ඩ්‍රොයිඩ් ඇමතුම් ලබා ගනී (තිරය භ්‍රමණය වන විට එය 100% ක නිශ්චිතභාවයකින් සිදු වේ, මන්දයත් සමස්ත උපාංග වින්‍යාසයම වෙනස් වී ඇති අතර ක්‍රියාකාරකම මුල සිටම නැවත නිර්මාණය කළ යුතුය).
විකී චිජ්වානි

20

මගේ ගැටළුව වූයේ මට අඛණ්ඩ පැවැත්ම අවශ්‍ය වූයේ යෙදුම් ජීවිත කාලය තුළ පමණි (එනම් එකම යෙදුම තුළ වෙනත් උප ක්‍රියාකාරකම් ආරම්භ කිරීම සහ උපාංගය භ්‍රමණය කිරීම ඇතුළුව තනි ක්‍රියාත්මක කිරීමකි). ඉහත පිළිතුරු වල විවිධ සංයෝජන මම උත්සාහ කළ නමුත් සෑම අවස්ථාවකම මට අවශ්‍ය දේ නොලැබුණි. අවසානයේදී මට වැඩ කළ දෙය වූයේ onCreate අතරතුරදී ඉතිරි කළ ඉන්ස්ටැන්ස්ටේට් වෙත යොමු කිරීමක් ලබා ගැනීමයි:

mySavedInstanceState=savedInstanceState;

මගේ විචල්‍යයේ අන්තර්ගතය මට අවශ්‍ය වූ විට ලබා ගැනීමට එය භාවිතා කරන්න.

if (mySavedInstanceState !=null) {
   boolean myVariable = mySavedInstanceState.getBoolean("MyVariable");
}

මම භාවිතා onSaveInstanceStateසහ onRestoreInstanceStateඉහත යෝජනා කරන පරිදි නමුත් මම මම ද භාවිතයෙන් හෝ එය (භාවිතා උදා වෙනස් වන විට විචල්ය බේරා ගැනීමට මගේ ක්රමය භාවිතා කළ හැකි අනුමාන putBoolean)


19

පිළිගත් පිළිතුර නිවැරදි වුවද, අයිස්පික් නම් පුස්තකාලයක් භාවිතා කරමින් ඇන්ඩ්‍රොයිඩ් හි ක්‍රියාකාරීත්වය සුරැකීමට වේගවත් හා පහසු ක්‍රමයක් තිබේ . අයිස්පික් යනු ඔබ වෙනුවෙන් තත්වය සුරැකීමට සහ ප්‍රතිෂ් oring ාපනය කිරීමට භාවිතා කරන සියලුම බොයිලේරු කේතයන් ගැන සැලකිලිමත් වන විවරණ සකසනයකි.

අයිස්පික් සමඟ මේ වගේ දෙයක් කිරීම:

class MainActivity extends Activity {
  @State String username; // These will be automatically saved and restored
  @State String password;
  @State int age;

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

මෙය කිරීම සමාන වේ:

class MainActivity extends Activity {
  String username;
  String password;
  int age;

  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putString("MyString", username);
    savedInstanceState.putString("MyPassword", password);
    savedInstanceState.putInt("MyAge", age); 
    /* remember you would need to actually initialize these variables before putting it in the
    Bundle */
  }

  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    username = savedInstanceState.getString("MyString");
    password = savedInstanceState.getString("MyPassword");
    age = savedInstanceState.getInt("MyAge");
  }
}

අයිස්පික් එහි තත්වය සුරකින ඕනෑම වස්තුවක් සමඟ ක්‍රියා කරයි Bundle.


16

ක්‍රියාකාරකමක් නිර්මාණය කළ විට එය onCreate () ක්‍රමය ලෙස හැඳින්වේ.

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

saveInstanceState යනු පළමු වරට ශුන්‍ය වන මිටි පන්තියේ වස්තුවකි, නමුත් එය ප්‍රතිනිර්මාණය කරන විට එහි අගයන් අඩංගු වේ. ක්‍රියාකාරකම් තත්ත්වය සුරැකීමට ඔබට SaveInstanceState () අභිබවා යා යුතුය.

   @Override
    protected void onSaveInstanceState(Bundle outState) {
      outState.putString("key","Welcome Back")
        super.onSaveInstanceState(outState);       //save state
    }

ඔබේ අගයන් outState.putString ("key", "Welcome Back") වැනි "outState" Bundle object තුළට දමා සුපිරි ලෙස ඇමතීමෙන් සුරකින්න. ක්‍රියාකාරකම් විනාශ වන විට එහි තත්වය බණ්ඩල් වස්තුව තුළ සුරැකෙන අතර onCreate () හෝ onRestoreInstanceState () හි විනෝදාස්වාදයෙන් පසු ප්‍රතිස්ථාපනය කළ හැකිය. OnCreate () සහ onRestoreInstanceState () වලින් ලැබෙන බණ්ඩලය සමාන වේ.

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          //restore activity's state
         if(savedInstanceState!=null){
          String reStoredString=savedInstanceState.getString("key");
            }
    }

හෝ

  //restores activity's saved state
 @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
      String restoredMessage=savedInstanceState.getString("key");
    }

15

මෙම වෙනස ක්‍රියාත්මක කිරීමට මූලික වශයෙන් ක්‍රම දෙකක් තිබේ.

  1. භාවිතා කිරීම onSaveInstanceState()සහ onRestoreInstanceState().
  2. පැහැදිලිව android:configChanges="orientation|screenSize".

දෙවන ක්‍රමය භාවිතා කිරීමට මම නිර්දේශ නොකරමි. මගේ එක් අත්දැකීමක දී එය පෝට්රේට් සිට භූ දර්ශනය දක්වා භ්‍රමණය වන අතර උපාංග තිරයෙන් අඩක් කළු වී ඇත.

ඉහත සඳහන් කළ පළමු ක්‍රමය භාවිතා කරමින්, දිශානතිය වෙනස් වූ විට හෝ වින්‍යාස වෙනස් කිරීමක් සිදු වූ විට අපට දත්ත දිගටම පැවතිය හැකිය. SaveInstance රාජ්‍ය වස්තුව තුළ ඔබට ඕනෑම ආකාරයක දත්ත ගබඩා කළ හැකි ක්‍රමයක් මම දනිමි.

උදාහරණය: ඔබට Json වස්තුව දිගටම පවත්වා ගැනීමට අවශ්‍ය නම් නඩුවක් සලකා බලන්න. getters සහ setters සමඟ ආදර්ශ පන්තියක් සාදන්න.

class MyModel extends Serializable{
JSONObject obj;

setJsonObject(JsonObject obj)
{
this.obj=obj;
}

JSONObject getJsonObject()
return this.obj;
} 
}

දැන් onCreate සහ onSaveInstanceState ක්‍රමයේ ඔබගේ ක්‍රියාකාරකම් වලදී පහත සඳහන් දෑ කරන්න. එය මේ වගේ දෙයක් වනු ඇත:

@override
onCreate(Bundle savedInstaceState){
MyModel data= (MyModel)savedInstaceState.getSerializable("yourkey")
JSONObject obj=data.getJsonObject();
//Here you have retained JSONObject and can use.
}


@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Obj is some json object 
MyModel dataToSave= new MyModel();
dataToSave.setJsonObject(obj);
oustate.putSerializable("yourkey",dataToSave); 

}

11

මෙහි සිට විග්රහය ස්ටීව් මොස්ලි 'පිළිතුර (විසින් ToolmakerSteve ) ඉදිරිදර්ශනය බවට බුදුන් (onPause, බටහිර පිරිවැය පැටලීම එදිරිව නැගෙනහිර පිරිවැය එදිරිව මුළු onSaveInstanceState දී) දේවල්

VVVK - මම අර්ධ වශයෙන් එකඟ නොවෙමි. යෙදුමකින් පිටවීමේ සමහර ක්‍රම onSaveInstanceState (oSIS) අවුලුවන්නේ නැත. මෙය oSIS හි ප්‍රයෝජනය සීමා කරයි. අවම මෙහෙයුම් පද්ධති සම්පත් සඳහා සහය දැක්වීම වටී, නමුත් යෙදුමකට පරිශීලකයා ඔවුන් සිටි තත්වයට නැවත පැමිණීමට අවශ්‍ය නම්, යෙදුම පිටවූ ආකාරය කුමක් වුවත්, ඒ වෙනුවට නිරන්තර ගබඩා ප්‍රවේශයක් භාවිතා කිරීම අවශ්‍ය වේ. බණ්ඩලය පරීක්ෂා කිරීම සඳහා මම onCreate භාවිතා කරමි, එය අස්ථානගත වී ඇත්නම්, නිරන්තර ගබඩාව පරීක්ෂා කරන්න . මෙය තීරණ ගැනීමේ කේන්ද්‍රීය වේ. මට බිඳවැටීමකින් හෝ පසු බොත්තම් පිටවීමකින් හෝ අභිරුචි මෙනු අයිතමයෙන් පිටවීමෙන් හෝ නැවත තිරය වෙත පිවිසිය හැකිය. - මෙවලම් සාදන්නා සැප්තැම්බර් 19 '15 ට 10:38 ට


10

කෝට්ලින් කේතය:

සුරකින්න:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState.apply {
        putInt("intKey", 1)
        putString("stringKey", "String Value")
        putParcelable("parcelableKey", parcelableObject)
    })
}

ඉන්පසු onCreate()හෝonRestoreInstanceState()

    val restoredInt = savedInstanceState?.getInt("intKey") ?: 1 //default int
    val restoredString = savedInstanceState?.getString("stringKey") ?: "default string"
    val restoredParcelable = savedInstanceState?.getParcelable<ParcelableClass>("parcelableKey") ?: ParcelableClass() //default parcelable

ඔබට විකල්ප ලබා ගැනීමට අවශ්‍ය නැතිනම් පෙරනිමි අගයන් එක් කරන්න


9

ක්‍රියාකාරකම් තත්ව දත්ත ගබඩා කර ගැනීම සඳහා onCreate(), පළමුව ඔබ විසින් අතිච්ඡාදනය SaveInstanceState(Bundle savedInstanceState)කිරීමේ ක්‍රමවේදය මඟින් saveInstanceState හි දත්ත සුරැකිය යුතුය .

ක්‍රියාකාරකම් විනාශ SaveInstanceState(Bundle savedInstanceState)කිරීමේ ක්‍රමය කැඳවූ විට ඔබට සුරැකීමට අවශ්‍ය දත්ත ඉතිරි වේ. onCreate()ක්‍රියාකාරකම් නැවත ආරම්භ වන විටද ඔබට එයම වේ . (ක්‍රියාකාරකම විනාශ වීමට පෙර ඔබ එහි යම් දත්තයක් ඉතිරි කර ඇති බැවින් saveInstanceState අහෝසි නොවේ)


6

මෙම ගැටළුව විසඳීමට සරල ඉක්මන් වන්නේ අයිස්පික් භාවිතා කිරීමයි

පළමුව, පුස්තකාලය පිහිටුවන්න app/build.gradle

repositories {
  maven {url "https://clojars.org/repo/"}
}
dependencies {
  compile 'frankiesardo:icepick:3.2.0'
  provided 'frankiesardo:icepick-processor:3.2.0'
}

දැන්, ක්‍රියාකාරකම තුළ තත්වය සුරැකෙන්නේ කෙසේදැයි පහත මෙම උදාහරණය පරීක්ෂා කරමු

public class ExampleActivity extends Activity {
  @State String username; // This will be automatically saved and restored

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

එය ක්‍රියාකාරීත්වය, කොටස් හෝ එහි වස්තුව මිටියක් මත අනුක්‍රමික කිරීමට අවශ්‍ය ඕනෑම වස්තුවක් සඳහා ක්‍රියා කරයි (උදා: මෝටාර්ගේ දර්ශන නියෝජිතයන්)

අභිරුචි දසුන් සඳහා නිදර්ශන රාජ්‍ය කේතය ජනනය කිරීමට අයිස්පික් හට හැකිය:

class CustomView extends View {
  @State int selectedPosition; // This will be automatically saved and restored

  @Override public Parcelable onSaveInstanceState() {
    return Icepick.saveInstanceState(this, super.onSaveInstanceState());
  }

  @Override public void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state));
  }

  // You can put the calls to Icepick into a BaseCustomView and inherit from it
  // All Views extending this CustomView automatically have state saved/restored
}

1
phralphspoon ඔව්, එය කොටස් හා අභිරුචි දර්ශනය සඳහා ක්‍රියා කරයි. කරුණාකර උදාහරණ කේතය පරීක්ෂා කරන්න. මම මගේ පිළිතුර සංස්කරණය කළා. තවත් කේත නියැදියක් සොයා ගැනීම සඳහා නිල ලිපි ලේඛන වෙත යාමට මම ඔබට යෝජනා කරමි github.com/frankiesardo/icepick .
THANN Phearum

He චෙතන් මෙහ්රා ඔබ අදහස් කළේ අභිරුචි දර්ශන පන්තිය නේද? එය අභිරුචි දසුනක් නම්, අපට CustomView හි ඉහත උදාහරණය මෙන් onSaveInstanceState සහ onRestoreInstanceState අභිබවා යා හැකිය.
THANN Phearum

මා අදහස් කළේ පන්ති වස්තුව ඇතුළත දර්ශන පන්තිය තුළ ය: පංතියේ අභිරුචි දසුන View @ STate ClassA a;} හෝ පන්තියේ CustomView දර්ශනය පුළුල් කරයි View @ රාජ්‍ය අභ්‍යන්තර පන්තිය {}}
චේතන් මෙහ්රා

@THANNPhearum මම එය වෙනත් ප්‍රශ්නයක් ලෙස ඇසිය යුතුද?
චෙතන් මෙහ්රා

මට පේනවා. එසේ නම්, ඔබේ පංතිය පාර්සල් කළ හැකි විය යුතුය. එහි ක්‍රියාකාරිත්වය, කොටස් හෝ එහි වස්තුව
මිටියක්

6

මගේ විසඳුම දෙස බලන්නේද නැද්ද යන්න නිශ්චිත නැත, නමුත් මම ViewModel තත්වය දිගටම පවත්වා ගැනීමට බැඳී සේවාවක් භාවිතා කරමි. ඔබ එය සේවාවේ මතකයේ ගබඩා කරන්නේද නැතහොත් එය SQLite දත්ත ගබඩාවකින් දිගටම ලබා ගන්නේද යන්න ඔබගේ අවශ්‍යතා මත රඳා පවතී. ඕනෑම රසයක සේවාවන් කරන්නේ මෙයයි, ඒවා යෙදුම් තත්වය පවත්වා ගැනීම සහ වියුක්ත පොදු ව්‍යාපාර තර්කනය වැනි සේවාවන් සපයයි.

ජංගම උපාංගවල ආවේනික මතකය සහ සැකසුම් අවහිරතා නිසා, මම ඇන්ඩ්‍රොයිඩ් දර්ශන වෙබ් පිටුවකට සමාන ආකාරයකින් සලකමි. පිටුව තත්වය නඩත්තු නොකරයි, එය තනිකරම ඉදිරිපත් කිරීමේ ස්ථර අංගයක් වන අතර එහි එකම අරමුණ යෙදුම් තත්වය ඉදිරිපත් කිරීම සහ පරිශීලක ආදානය පිළිගැනීමයි. වෙබ් යෙදුම් ගෘහ නිර්මාණ ශිල්පයේ මෑත කාලීන ප්‍රවණතා මඟින් පැරණි-පැරණි ආකෘතිය, දර්ශනය, පාලක (එම්වීසී) රටාව භාවිතා කරයි, එහිදී පිටුව දර්ශනය, වසම් දත්ත ආදර්ශය වන අතර පාලකය වෙබ් සේවාවක් පිටුපස වාඩි වී සිටී. එකම රටාව ඇන්ඩ්‍රොයිඩ් හි දර්ශනය සමඟ භාවිතා කළ හැකිය, හොඳයි ... දර්ශනය, ආකෘතිය ඔබේ ඩොමේන් දත්ත වන අතර පාලකය ඇන්ඩ්‍රොයිඩ් බැඳී ඇති සේවාවක් ලෙස ක්‍රියාත්මක වේ. පාලකය සමඟ අන්තර් ක්‍රියා කිරීමට ඔබට දර්ශනයක් අවශ්‍ය වූ විට, එය ආරම්භයේදී / නැවත ආරම්භ කර එය නැවැත්වීම / විරාමය මත බැඳ තබන්න.

මෙම ප්‍රවේශය මඟින් ඔබ සැමට වෙන්කිරීමේ සැලසුම් මූලධර්මය බලාත්මක කිරීමේ අමතර ප්‍රසාද දීමනාවක් ලබා දෙන අතර එමඟින් ඔබ සියලු යෙදුම් ව්‍යාපාර තර්කනය ඔබේ සේවාවට ගෙන යා හැකි අතර එමඟින් විවිධ අදහස් හරහා අනුපිටපත් තර්කනය අඩු කරන අතර තවත් වැදගත් සැලසුම් මූලධර්මයක් වන තනි වගකීම බලාත්මක කිරීමට දර්ශනයට ඉඩ දෙයි.


5

කොට්ලින්

ඔබ යටපත් කිරීම කළ යුතුය onSaveInstanceStateසහonRestoreInstanceState ඔබේ විචල්ය ගබඩා කිරීම සහ ඔබ දිගටම පවතින වීමට අවශ්ය

ජීවන චක්‍ර ප්‍රස්ථාරය

ගබඩා විචල්යයන්

public override fun onSaveInstanceState(savedInstanceState: Bundle) {
    super.onSaveInstanceState(savedInstanceState)

    // prepare variables here
    savedInstanceState.putInt("kInt", 10)
    savedInstanceState.putBoolean("kBool", true)
    savedInstanceState.putDouble("kDouble", 4.5)
    savedInstanceState.putString("kString", "Hello Kotlin")
}

විචල්යයන් ලබා ගන්න

public override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)

    val myInt = savedInstanceState.getInt("kInt")
    val myBoolean = savedInstanceState.getBoolean("kBool")
    val myDouble = savedInstanceState.getDouble("kDouble")
    val myString = savedInstanceState.getString("kString")
    // use variables here
}

2

දැන් ඇන්ඩ්‍රොයිඩ් විසින් තත්වය සුරැකීම සඳහා ViewModels සපයයි , ඔබ එය saveInstanceState වෙනුවට භාවිතා කිරීමට උත්සාහ කළ යුතුය.


3
මෙය සත්‍ය නොවේ. ප්‍රලේඛනයෙන්: "සුරකින ලද අවස්ථා තත්වයට වඩා වෙනස්ව, පද්ධතිය ආරම්භ කරන ලද ක්‍රියාවලියකදී ViewModels විනාශ වේ. මේ නිසා ඔබ ViewModel වස්තු onSaveInstanceState () (හෝ වෙනත් තැටි නොනැසී පැවතීම) සමඟ ඒකාබද්ධව භාවිතා කළ යුතුය. පද්ධති මරණයෙන් පසු ආකෘති නැවත දත්ත පූරණය කරයි.
වියචෙස්ලාව් මාටිනෙන්කෝ

පසුබිමෙහි අවසරයන් වෙනස් වීමත් සමඟ මේ සඳහා දිව යන්න.
බ්‍රිල් පැපින්

මම එකඟ වෙමි, "පද්ධතිය ආරම්භ කළ ක්‍රියාවලිය මරණයට මුහුණ දීමට ඔබට අවශ්‍ය නම්, ඔබට උපස්ථයක් ලෙස onSaveInstanceState () භාවිතා කිරීමට අවශ්‍ය විය හැකිය."
ෂාර්

2

කිසිදු ක්‍රමයක් ක්‍රියාත්මක නොකර ඇන්ඩ්‍රොයිඩ් විසින් ප්‍රාන්ත සුරැකීමට ක්‍රමයක් තිබේ. ඔබගේ ක්‍රියාකාරී ප්‍රකාශනයේ ප්‍රකාශයට මෙම රේඛාව එක් කරන්න:

android:configChanges="orientation|screenSize"

එය මේ වගේ විය යුතුයි:

<activity
    android:name=".activities.MyActivity"
    android:configChanges="orientation|screenSize">
</activity>

මෙහි ඔබට මෙම දේපල පිළිබඳ වැඩි විස්තර සොයාගත හැකිය.

අතින් හැසිරවීමට වඩා ඇන්ඩ්‍රොයිඩ් ඔබට මෙය හැසිරවීමට ඉඩ දීම රෙකමදාරු කරනු ලැබේ.


2
මෙය රාජ්‍යය සුරැකීමට කිසිදු සම්බන්ධයක් නැත, ඔබ දිශානතියේ වෙනස්කම් අත්හරින්න, ඔබේ යෙදුම නැවත ආරම්භ කර විරාමයක් තබා විවිධ සිදුවීම් සඳහා ඕනෑම වේලාවක නැවත ආරම්භ කළ හැකි බව මතක තබා ගන්න
ස්වාමීන්-රැල්ෆ්-ඇඩොල්ෆ්

1
මෙම පිළිතුර දිශානතිය වෙනස් වූ විට රාජ්‍යය සුරැකීමට අවශ්‍ය වන අතර සංකීර්ණ ක්‍රමයක් අවබෝධ කර ගැනීම සහ ක්‍රියාත්මක කිරීම වළක්වා ගැනීමට අවශ්‍ය
අයටයි

ඔබගේ අදහස මා දකින තරමට, රාජ්‍යය සුරැකීමට අරගල කරන බොහෝ අය කොටස් භාවිතා කරන්නේ ක්‍රියාකාරකම් වල හැඳුනුම්පතක් ඇති තාක් කල් UI සංරචක වල ප්‍ර stat ප්තිය සුරැකෙන බැවිනි, නමුත් කොටස් වඩාත් විශේෂ වේ, මම වරක් කොටස් භාවිතා කළ නමුත් මම කිසි විටෙකත් භාවිතා නොකරමි ඒවා නැවත සුරැකීමේ උදාහරණය සමඟ කටයුතු කිරීමට වේදනාකාරී විය
ස්වාමීන්-රැල්ෆ්-ඇඩොල්ෆ්

1

ඉතිරි කළ යුත්තේ කුමක්ද සහ නොකළ යුත්තේ කුමක්ද?

කවදා හෝ කල්පනා කළේ ඇයි? EditTextදිශානතිය වෙනස් වන අතර ස්වයංක්‍රීයව සුරැකෙන්නේ ? හොඳයි, මෙම පිළිතුර ඔබ වෙනුවෙන් ය.

ක්‍රියාකාරකමක අවස්ථාවක් විනාශ වූ විට සහ පද්ධතිය නව අවස්ථාවක් ප්‍රතිනිර්මාණය කළ විට (නිදසුනක් ලෙස, වින්‍යාස වෙනස් කිරීම). එය පැරණි ක්‍රියාකාරකම් තත්වයේ ( උදාහරණ තත්වය) සුරකින ලද දත්ත කට්ටලයක් භාවිතා කර එය ප්‍රතිනිර්මාණය කිරීමට උත්සාහ කරයි ) .

නිදර්ශන තත්වය යනු වස්තුවක ගබඩා කර ඇති යතුරු අගය යුගල එකතුවකි Bundle.

පෙරනිමියෙන් පද්ධතිය බණ්ඩලයේ ඇති දර්ශන වස්තු සුරකිනු ඇත.

  • තුළ පෙළ EditText
  • ListView, ආදියෙහි අනුචලන පිහිටීම .

නිදර්ශන තත්වයේ කොටසක් ලෙස සුරැකීමට ඔබට වෙනත් විචල්‍යයක් අවශ්‍ය නම් ඔබ ඉක්මවා යා යුතුය onSavedInstanceState(Bundle savedinstaneState) ක්‍රමවේදය .

උදාහරණයක් වශයෙන්, int currentScore ක්‍රීඩා ක්‍රියාකාරකමක

දත්ත සුරැකීමේදී onSavedInstanceState (Bundle saveinstaneState) පිළිබඳ වැඩි විස්තර

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

එබැවින් වැරදීමකින් ඔබට ඇමතීමට අමතක වුවහොත් super.onSaveInstanceState(savedInstanceState);පෙරනිමි හැසිරීම ක්‍රියා නොකරනු ඇත, එනම් EditText හි පෙළ සුරැකෙන්නේ නැත.

ක්‍රියාකාරකම් තත්වය ප්‍රතිස්ථාපනය කිරීම සඳහා තෝරාගත යුත්තේ කුමක්ද?

 onCreate(Bundle savedInstanceState)

හෝ

onRestoreInstanceState(Bundle savedInstanceState)

මෙම ක්‍රම දෙකම එකම බණ්ඩල් වස්තුවක් ලබා ගනී, එබැවින් ඔබේ ප්‍රතිස්ථාපන තර්කනය ඔබ ලියන්නේ කොතැනද යන්න ගැටළුවක් නොවේ. එකම වෙනස එයයිonCreate(Bundle savedInstanceState) ක්‍රමයේදී ඔබට ශුන්‍ය චෙක්පතක් ලබා දිය යුතු අතර එය දෙවන අවස්ථාවෙහිදී අවශ්‍ය නොවේ. වෙනත් පිළිතුරු දැනටමත් කේත ස්නිපෙට් ඇත. ඔබට ඒවා යොමු කළ හැකිය.

OnRestoreInstanceState (Bundle saveinstaneState) පිළිබඳ වැඩි විස්තර

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from the saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}

සෑම විටම අමතන්න super.onRestoreInstanceState(savedInstanceState);එවිට පද්ධතිය පෙරනිමියෙන් දර්ශන ධූරාවලිය යථා තත්වයට පත් කරයි

පාරිතෝෂිකය

මෙම onSaveInstanceState(Bundle savedInstanceState)පරිශීලකයා ක්රියාකාරකම් නැවත එන්න බලාපොරොත්තු විට පමණක් පද්ධතිය මඟින් පළ කළහ ඇත. උදාහරණයක් ලෙස, ඔබ App X භාවිතා කරන අතර හදිසියේම ඔබට ඇමතුමක් ලැබේ. ඔබ අමතන්නාගේ යෙදුම වෙත ගොස් X යෙදුම වෙත නැවත පැමිණේ. මෙම අවස්ථාවේදී onSaveInstanceState(Bundle savedInstanceState)ක්‍රමය ක්‍රියාත්මක වේ.

පරිශීලකයෙකු පසුපස බොත්තම එබුවහොත් මෙය සලකා බලන්න. පරිශීලකයා නැවත ක්‍රියාකාරකමට පැමිණීමට අදහස් නොකරන බව උපකල්පනය කෙරේ, එබැවින් මෙම අවස්ථාවේ දීonSaveInstanceState(Bundle savedInstanceState) පද්ධතිය මඟින් ආයාචනා නොකෙරේ. දත්ත සුරැකීමේදී ඔබ සියලු අවස්ථා සලකා බැලිය යුතුය.

අදාළ සබැඳි:

පෙරනිමි හැසිරීම පිළිබඳ නිරූපණය
ඇන්ඩ්‍රොයිඩ් නිල ප්‍රලේඛනය .


1

දැන් දර්ශන ආකෘතියේ ක්‍රම 2 ක් කිරීම අර්ථවත් කරයි. ඔබට පළමුවැන්න සුරකින ලද අවස්ථාවක් ලෙස සුරැකීමට අවශ්‍ය නම්: ඔබට https://developer.android.com/topic/libraries/architecture/viewmodel-savedstate#java වැනි දර්ශන ආකෘතියේ රාජ්‍ය පරාමිතිය එක් කළ හැකිය.

හෝ ඔබට දර්ශන මාදිලියේ විචල්‍යයන් හෝ වස්තු සුරැකිය හැක, මේ අවස්ථාවේ දී ක්‍රියාකාරීත්වය විනාශ වන තෙක් දර්ශන ආකෘතිය ජීවන චක්‍රය රඳවා තබා ගනී.

public class HelloAndroidViewModel extends ViewModel {
   public Booelan firstInit = false;

    public HelloAndroidViewModel() {
        firstInit = false;
    }
    ...
}

public class HelloAndroid extends Activity {

  private TextView mTextView = null;
  HelloAndroidViewModel viewModel = ViewModelProviders.of(this).get(HelloAndroidViewModel.class);
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTextView = new TextView(this);

    //Because even if the state is deleted, the data in the viewmodel will be kept because the activity does not destroy
    if(!viewModel.firstInit){
        viewModel.firstInit = true
        mTextView.setText("Welcome to HelloAndroid!");
    }else{
       mTextView.setText("Welcome back.");
    }

    setContentView(mTextView);
  }
}

ඔබ හරි, නමුත් මෙම පුස්තකාලය තවමත් මුදා හැර ඇති බැවින් මම බලා සිටිය යුතු යැයි මම සිතමි ...
ෂාර්

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.