আমি Activity
পদ্ধতিগুলি onSaveInstanceState()
এবং ব্যবহার করে রাষ্ট্রের সংরক্ষণ এবং পুনরুদ্ধার করার চেষ্টা করছি onRestoreInstanceState()
।
সমস্যাটি হ'ল এটি onRestoreInstanceState()
পদ্ধতিতে প্রবেশ করে না । কেউ আমাকে বোঝাতে পারেন কেন এটি?
আমি Activity
পদ্ধতিগুলি onSaveInstanceState()
এবং ব্যবহার করে রাষ্ট্রের সংরক্ষণ এবং পুনরুদ্ধার করার চেষ্টা করছি onRestoreInstanceState()
।
সমস্যাটি হ'ল এটি onRestoreInstanceState()
পদ্ধতিতে প্রবেশ করে না । কেউ আমাকে বোঝাতে পারেন কেন এটি?
উত্তর:
সাধারণত আপনি নিজের রাজ্যে পুনরুদ্ধার করেন onCreate()
। এটি onRestoreInstanceState()
পাশাপাশি পুনরুদ্ধার করা সম্ভব তবে খুব সাধারণ নয়। ( onRestoreInstanceState()
পরে বলা হয় onStart()
, যেখানে onCreate()
আগে বলা হয় onStart()
।
এতে মানগুলি সংরক্ষণের জন্য পুট পদ্ধতিগুলি ব্যবহার করুন onSaveInstanceState()
:
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
icicle.putLong("param", value);
}
এবং মানগুলি এখানে পুনরুদ্ধার করুন onCreate()
:
public void onCreate(Bundle icicle) {
if (icicle != null){
value = icicle.getLong("param");
}
}
onRestoreInstanceState()
ওএস দ্বারা হত্যা করার পরে কার্যকলাপ পুনরায় শুরু করার সময় কেবল তাকে ডাকা হয় is এ জাতীয় পরিস্থিতি যখন ঘটে:
বিপরীতে: আপনি যদি নিজের কার্যকলাপে থাকেন এবং আপনি Back
ডিভাইসে বোতামটি হিট করেন তবে আপনার ক্রিয়াকলাপটি সমাপ্ত হবে () এড (যেমন এটিকে ডেস্কটপ অ্যাপ্লিকেশন হিসাবে প্রস্থান হিসাবে মনে করবেন) এবং পরের বার আপনি আপনার অ্যাপ্লিকেশনটি শুরু করলে এটি "টাটকা" শুরু হবে, অর্থাত্ ছাড়া সংরক্ষণের অবস্থা কারণ আপনি যখন আঘাত করবেন তখন আপনি ইচ্ছাকৃতভাবে এটিকে প্রস্থান করেছেন Back
।
বিভ্রান্তির অন্যান্য উত্স হ'ল যখন কোনও অ্যাপ্লিকেশন অন্য অ্যাপ্লিকেশনটির উপর ফোকাস হারায় onSaveInstanceState()
তখন তাকে ডাকা হয় তবে আপনি যখন আপনার অ্যাপ্লিকেশনটিতে ফিরে যান তখন কল করা onRestoreInstanceState()
যাবেনা। এটি মূল প্রশ্নে বর্ণিত কেস, অর্থাত্ যদি আপনার ক্রিয়াকলাপটি সেই সময়কালে হত্যা না করা হত যখন অন্য ক্রিয়াকলাপটি সামনে ছিল তখন তাকে onRestoreInstanceState()
বলা হবে না কারণ আপনার কার্যকলাপটি বেশ "জীবিত"।
সব মিলিয়ে ডকুমেন্টেশনে যেমন বলা হয়েছে onRestoreInstanceState()
:
বেশিরভাগ বাস্তবায়নগুলি কেবল তাদের রাজ্য পুনরুদ্ধার করতে অনক্রিট (বান্ডিল) ব্যবহার করবে তবে প্রাথমিকভাবে সমস্ত কাজ সম্পন্ন করার পরে এখানে কিছু করা সুবিধাজনক হবে বা আপনার ডিফল্ট বাস্তবায়নটি ব্যবহার করতে হবে কিনা তা সিদ্ধান্তের জন্য সাবক্লাসগুলিকে অনুমতি দেওয়া হবে। এই পদ্ধতির ডিফল্ট বাস্তবায়নটি পূর্বে onSaveInstanceState (বান্ডিল) দ্বারা হিমায়িত করা হয়েছে এমন কোনও দর্শন অবস্থার পুনরুদ্ধার করে।
যেমনটি আমি এটি পড়েছি: onRestoreInstanceState()
আপনি সাবক্লাসিং না করে ওভাররাইড করার কোনও কারণ নেই Activity
এবং এটি প্রত্যাশিত যে কেউ আপনার সাবক্লাসটি সাবক্লাস করবে।
আপনি যে রাষ্ট্রটি সংরক্ষণ করেছেন onSaveInstanceState()
সেটি পরে onCreate()
পদ্ধতি আহ্বানে পাওয়া যায় । সুতরাং আপনার ক্রিয়াকলাপের অবস্থা পুনরুদ্ধার করতে onCreate
(এবং এর Bundle
পরামিতি) ব্যবহার করুন ।
কর্মক্ষেত্র হিসাবে, আপনি ক্রিয়াকলাপ এ শুরু করার জন্য যে ইন্টেন্টটি ব্যবহার করেন তার মধ্যে আপনি যে ডেটা বজায় রাখতে চান তা দিয়ে আপনি একটি বান্ডিল সঞ্চয় করতে পারেন A.
Intent intent = new Intent(this, ActivityA.class);
intent.putExtra("bundle", theBundledData);
startActivity(intent);
ক্রিয়াকলাপ এটিকে এটিকে আবার কার্যকলাপ বিতে পাঠাতে হবে আপনি কার্যকলাপ বি এর অনক্রিট পদ্ধতিতে অভিপ্রায়টি পুনরুদ্ধার করতে পারবেন।
Intent intent = getIntent();
Bundle intentBundle;
if (intent != null)
intentBundle = intent.getBundleExtra("bundle");
// Do something with the data.
আরেকটি ধারণা হ'ল ক্রিয়াকলাপের স্টোর সংরক্ষণের জন্য একটি সংগ্রহশালা তৈরি করা এবং আপনার প্রতিটি ক্রিয়াকলাপের সেই শ্রেণিটি উল্লেখ করা (একক একটি কাঠামো ব্যবহার করা সম্ভব)) যদিও এটি করার চেয়ে এটি সম্ভবত বেশি সমস্যা trouble
মূল জিনিসটি আপনি যদি সংরক্ষণ না করেন onSaveInstanceState()
তবে onRestoreInstanceState()
ডাকা হবে না। এটি restoreInstanceState()
এবং এর মধ্যে প্রধান পার্থক্য onCreate()
। আপনি সত্যিই কিছু সঞ্চয় করেছেন তা নিশ্চিত করুন। সম্ভবত এটি আপনার সমস্যা।
আমি দেখতে পেলাম যে অনভিজ্ঞাস্বন্ধিকার স্টেটটি সর্বদা ডাকা হয় যখন অন্য কোনও ক্রিয়াকলাপ সম্মুখের দিকে আসে। এবং তাই অনটপ।
তবে, অনস্ট্রেইটস ইনস্ট্যান্সস্টেট কেবল তখনই কল করা হয়েছিল যখন অনক্রিট এবং অন স্টার্টকেও ডাকা হত। এবং, অনক্রিট এবং অন স্টার্ট সবসময় কল করা হয়নি।
সুতরাং দেখে মনে হচ্ছে অ্যাকডিয়াটি ব্যাকগ্রাউন্ডে সরে গেলেও অ্যান্ড্রয়েড সর্বদা রাষ্ট্রের তথ্য মুছে দেয় না। তবে, এটি কেবল নিরাপদ থাকার জন্য রাষ্ট্রকে বাঁচাতে লাইফসাইकल পদ্ধতিগুলি কল করে। সুতরাং, যদি রাজ্যটি মুছে ফেলা না হয়, তবে অ্যান্ড্রয়েড রাষ্ট্রের পুনরুদ্ধার করার জন্য জীবনচক্র পদ্ধতিগুলি কল করে না কারণ তাদের প্রয়োজন নেই।
চিত্র 2 এটি বর্ণনা করে।
এটি দরকার নেই যে অনারস্টোরইনস্ট্যান্সস্টেট সর্বদা অন সেভ ইনস্টান্সস্টেটের পরে ডাকা হবে।
দ্রষ্টব্য: অনিয়ন্ত্রনস্ট্যান্সস্টেটটি সর্বদা ডাকা হবে, যখন ক্রিয়াকলাপটি ঘোরানো হয় (যখন ওরিয়েন্টেশন পরিচালনা করা হয় না) বা আপনার ক্রিয়াকলাপটি খুলুন এবং তারপরে অন্যান্য অ্যাপ্লিকেশনগুলি খুলুন যাতে আপনার ক্রিয়াকলাপের উদাহরণটি ওএস দ্বারা মেমরি থেকে সাফ হয়ে যায়।
ডকুমেন্টেশন থেকে পুনরুদ্ধার ক্রিয়াকলাপ ইউআই রাজ্য সংরক্ষণের উদাহরণ ব্যবহার করে এটি বর্ণিত হয়েছে:
অনক্রিট () এর সময় রাজ্য পুনরুদ্ধার করার পরিবর্তে আপনি onRestoreInstanceState () প্রয়োগ করতে বেছে নিতে পারেন, যা সিস্টেমটি স্টার্ট () পদ্ধতির পরে কল করে। সিস্টেমটি রিস্টোরইনস্ট্যান্স স্টেটকে কল করে কেবল তখনই যদি পুনরুদ্ধার করার জন্য কোনও সেভ স্টেট থাকে, সুতরাং আপনার বান্ডেলটি নাল কিনা তা পরীক্ষা করার দরকার নেই :
আইএমও, এটি অনক্রিটে পরীক্ষা করার চেয়ে আরও সুস্পষ্ট উপায় এবং একক দায়িত্ববোধ নীতিটির সাথে আরও ভাল ফিট করে।
আমার ক্ষেত্রে, onRestoreInstanceState
যখন ডিভাইস ওরিয়েন্টেশন পরিবর্তনের পরে ক্রিয়াকলাপটি পুনর্গঠন করা হয়েছিল তখন ডাকা হয়েছিল। onCreate(Bundle)
প্রথমে বলা হয়েছিল, তবে আমার কাছে সেট করা কী / মানগুলি বান্ডলে নেই onSaveInstanceState(Bundle)
।
ঠিক পরে, onRestoreInstanceState(Bundle)
এমন একটি বান্ডিল দিয়ে ডাকা হত যার সঠিক কী / মান ছিল।
আমি কেবল এটির মধ্যে দৌড়ে এসে দেখছিলাম যে ডকুমেন্টেশনের আমার উত্তর আছে:
"এই ফাংশনটি কখনই শূন্য অবস্থার সাথে ডাকা হবে না।"
আমার ক্ষেত্রে, আমি ভাবছিলাম কেন প্রাথমিক ইনস্ট্যান্টেশন করার জন্য কেন অনিয়ন্ত্রনস্ট্যান্স স্টেটকে ডাকা হচ্ছে না। এর অর্থ হ'ল আপনি যদি কিছু সঞ্চয় না করেন তবে আপনার দৃষ্টিভঙ্গি পুনর্গঠন করতে গেলে কল করা হবে না।
আমি এটি করতে পারি (দুঃখিত এটি সি # জাভা নয় তবে এটি কোনও সমস্যা নয় ...):
private int iValue = 1234567890;
function void MyTest()
{
Intent oIntent = new Intent (this, typeof(Camera2Activity));
Bundle oBundle = new Bundle();
oBundle.PutInt("MYVALUE", iValue); //=> 1234567890
oIntent.PutExtras (oBundle);
iRequestCode = 1111;
StartActivityForResult (oIntent, 1111);
}
ফলাফলের জন্য আপনার ক্রিয়াকলাপে
private int iValue = 0;
protected override void OnCreate(Bundle bundle)
{
Bundle oBundle = Intent.Extras;
if (oBundle != null)
{
iValue = oBundle.GetInt("MYVALUE", 0);
//=>1234567890
}
}
private void FinishActivity(bool bResult)
{
Intent oIntent = new Intent();
Bundle oBundle = new Bundle();
oBundle.PutInt("MYVALUE", iValue);//=>1234567890
oIntent.PutExtras(oBundle);
if (bResult)
{
SetResult (Result.Ok, oIntent);
}
else
SetResult(Result.Canceled, oIntent);
GC.Collect();
Finish();
}
অবশেষে
protected override void OnActivityResult(int iRequestCode, Android.App.Result oResultCode, Intent oIntent)
{
base.OnActivityResult (iRequestCode, oResultCode, oIntent);
iValue = oIntent.Extras.GetInt("MYVALUE", -1); //=> 1234567890
}