আমি এই উত্তরটি '09-এ ফিরে লিখেছিলাম যখন অ্যান্ড্রয়েড তুলনামূলকভাবে নতুন ছিল, এবং অ্যান্ড্রয়েড বিকাশে অনেকগুলি প্রতিষ্ঠিত নয়। আমি এই পোস্টের নীচে একটি দীর্ঘ সংযোজন যুক্ত করেছি, কিছু সমালোচনা সম্বোধন করে, এবং সাবক্লাসিং অ্যাপ্লিকেশন না করে সিঙ্গেলটনের ব্যবহারের সাথে আমার যে দার্শনিক মতবিরোধ রয়েছে তা বিশদ বর্ণনা করছি। এটি আপনার নিজের ঝুঁকিতে পড়ুন।
মূল উত্তর:
আপনি যে সাধারণ সমস্যাটির মুখোমুখি হচ্ছেন তা হ'ল কীভাবে বেশ কয়েকটি ক্রিয়াকলাপ এবং আপনার অ্যাপ্লিকেশনের সমস্ত অংশ জুড়ে রাষ্ট্র সংরক্ষণ করা যায়। একটি স্ট্যাটিক ভেরিয়েবল (উদাহরণস্বরূপ, একটি সিঙ্গলটন) এটি অর্জনের একটি সাধারণ জাভা উপায়। তবে আমি খুঁজে পেয়েছি যে, অ্যান্ড্রয়েডে আরও মার্জিত উপায় হ'ল অ্যাপ্লিকেশন প্রসঙ্গে আপনার রাষ্ট্রকে যুক্ত করা।
যেমন আপনি জানেন, প্রতিটি ক্রিয়াকলাপ একটি প্রসঙ্গও, যা বিস্তৃত অর্থে এর কার্যকরকরণ পরিবেশ সম্পর্কে তথ্য। আপনার অ্যাপ্লিকেশনটির একটি প্রসঙ্গও রয়েছে এবং অ্যান্ড্রয়েড গ্যারান্টি দেয় যে এটি আপনার অ্যাপ্লিকেশন জুড়ে একক উদাহরণ হিসাবে উপস্থিত থাকবে।
এটি করার উপায় হ'ল android.app . প্রয়োগের নিজস্ব সাবক্লাস তৈরি করা এবং তারপরে আপনার ম্যানিফেস্টে অ্যাপ্লিকেশন ট্যাগে সেই শ্রেণিটি নির্দিষ্ট করা। এখন অ্যান্ড্রয়েড স্বয়ংক্রিয়ভাবে সেই শ্রেণীর একটি উদাহরণ তৈরি করবে এবং আপনার সম্পূর্ণ অ্যাপ্লিকেশনের জন্য এটি উপলব্ধ করবে। আপনি এটি যে কোনও থেকে অ্যাক্সেস করতে পারেনcontext
Context.getApplicationContext()
পদ্ধতি ব্যবহার করে ( Activity
এমন পদ্ধতিও দেয় getApplication()
যা ঠিক একই প্রভাব ফেলে)। নিম্নলিখিতটি একটি চূড়ান্ত সরলীকৃত উদাহরণ, অনুসরণ করার জন্য সতর্কতা সহ:
class MyApp extends Application {
private String myState;
public String getState(){
return myState;
}
public void setState(String s){
myState = s;
}
}
class Blah extends Activity {
@Override
public void onCreate(Bundle b){
...
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}
এটি মূলত স্ট্যাটিক ভেরিয়েবল বা সিঙ্গলটন ব্যবহার করার মতো একই প্রভাব ফেলে তবে বিদ্যমান অ্যান্ড্রয়েড কাঠামোর সাথে বেশ ভালভাবে সংহত করে। নোট করুন যে এটি প্রক্রিয়াগুলি জুড়ে কাজ করবে না (আপনার অ্যাপ্লিকেশনটি একাধিক প্রক্রিয়াযুক্ত বিরলগুলির মধ্যে একটি হওয়া উচিত)।
উপরের উদাহরণ থেকে কিছু লক্ষণীয়; ধরুন আমরা এর পরিবর্তে কিছু করেছিলাম:
class MyApp extends Application {
private String myState = /* complicated and slow initialization */;
public String getState(){
return myState;
}
}
এখন এই ধীর সূচনা (যেমন হিট ডিস্ক, হিটিং নেটওয়ার্ক, কোনও কিছু ব্লক করা ইত্যাদি) প্রতিবার অ্যাপ্লিকেশন তাত্ক্ষণিকভাবে সঞ্চালিত হবে! আপনি ভাবতে পারেন, ভাল, প্রক্রিয়াটির জন্য এটি কেবল একবার এবং আমাকে যাইহোক খরচ দিতে হবে, তাই না? উদাহরণস্বরূপ, ডায়ান হ্যাকোর্ন নীচে যেমন উল্লেখ করেছেন, আপনার প্রক্রিয়াটি তাত্ক্ষণিকভাবে করা সম্ভব - ঠিক করা- একটি ব্যাকগ্রাউন্ড সম্প্রচার ইভেন্ট পরিচালনা করতে। যদি আপনার সম্প্রচার প্রক্রিয়াজাতকরণটির এই রাজ্যের কোনও প্রয়োজন না থাকে তবে আপনি সম্ভাব্যভাবে কিছুই এবং অবিচ্ছিন্ন ক্রিয়াকলাপের পুরো সিরিজটি সম্পন্ন করেছেন। অলস তাত্পর্য এখানে গেমের নাম। নিম্নলিখিতটি অ্যাপ্লিকেশন ব্যবহারের কিছুটা জটিল পদ্ধতি যা ব্যবহারের সহজতম ব্যতীত অন্য কোনও কিছুর জন্য আরও বেশি অর্থবোধ করে:
class MyApp extends Application {
private MyStateManager myStateManager = new MyStateManager();
public MyStateManager getStateManager(){
return myStateManager ;
}
}
class MyStateManager {
MyStateManager() {
/* this should be fast */
}
String getState() {
/* if necessary, perform blocking calls here */
/* make sure to deal with any multithreading/synchronicity issues */
...
return state;
}
}
class Blah extends Activity {
@Override
public void onCreate(Bundle b){
...
MyStateManager stateManager = ((MyApp)getApplicationContext()).getStateManager();
String state = stateManager.getState();
...
}
}
যদিও আমি এখানে আরও মার্জিত সমাধান হিসাবে সিঙ্গলেটগুলি ব্যবহার করার জন্য অ্যাপ্লিকেশন সাবক্লাসিং পছন্দ করি, আমি বরং অ্যাপ্লিকেশন সাবক্লাসের সাথে সংযুক্ত রাষ্ট্রের পারফরম্যান্স এবং মাল্টিথ্রেডিংয়ের অন্তর্ভুক্তির মাধ্যমে মোটেও চিন্তা না করার জন্য বিকাশকারীরা সত্যই প্রয়োজনে সিলেটলেট ব্যবহার করতে চাই।
দ্রষ্টব্য 1: এছাড়াও এন্টিকাএফ মন্তব্য হিসাবে, আপনার অ্যাপ্লিকেশনটিতে আপনার অ্যাপ্লিকেশনকে ওভাররাইডকে সঠিকভাবে বেঁধে রাখতে ম্যানিফেস্ট ফাইলটিতে একটি ট্যাগ প্রয়োজনীয়। আবার আরও তথ্যের জন্য অ্যান্ড্রয়েড ডক্স দেখুন। একটি উদাহরণ:
<application
android:name="my.application.MyApp"
android:icon="..."
android:label="...">
</application>
দ্রষ্টব্য 2: ব্যবহারকারী 608578 নীচে জিজ্ঞাসা করছে যে এটি কীভাবে নেটিভ অবজেক্ট লাইফসাইকেলগুলি পরিচালনা করে? আমি অল্প অল্প সময়েই অ্যান্ড্রয়েডের সাথে নেটিভ কোড ব্যবহারের গতি বাড়িয়ে তুলছি না এবং এটি কীভাবে আমার সমাধানের সাথে ইন্টারেক্ট করবে তা জবাব দেওয়ার জন্য আমি যোগ্য নই। কারও কাছে যদি এর উত্তর থাকে তবে আমি তাদের creditণ দিতে এবং সর্বাধিক দৃশ্যমানতার জন্য তথ্যটি এই পোস্টে রাখতে প্রস্তুত।
সংযোজন:
কিছু লোক যেমন উল্লেখ করেছে যে এটি স্থির অবস্থার জন্য কোনও সমাধান নয় , এমন কিছু যা সম্ভবত আমার মূল উত্তরে আরও জোর দেওয়া উচিত ছিল। অর্থাৎ এটি ব্যবহারকারী বা অন্যান্য তথ্য সংরক্ষণের সমাধান হিসাবে বোঝানো হচ্ছে না যা অ্যাপ্লিকেশন লাইফটাইম জুড়ে থাকবে। সুতরাং, আমি নীচে বেশিরভাগ সমালোচনা বিবেচনা করি যে কোনও সময় অ্যাপ্লিকেশন হত্যা করা ইত্যাদি সম্পর্কিত ... ইত্যাদি, যে কোনও কিছু যা ডিস্কে অবিচল থাকার প্রয়োজন হয় তা অ্যাপ্লিকেশন সাবক্লাসের মাধ্যমে সংরক্ষণ করা উচিত নয়। এটি অস্থায়ী, সহজে পুনরায় তৈরিযোগ্য অ্যাপ্লিকেশন স্টেট (কোনও ব্যবহারকারী উদাহরণ হিসাবে লগ ইন করা হয়েছে কিনা) এবং উপাদানগুলি যা একক উদাহরণ (অ্যাপ্লিকেশন নেটওয়ার্ক ম্যানেজার হিসাবে উদাহরণস্বরূপ) সংরক্ষণ করার সমাধান হিসাবে বোঝানো হয়েছে ( নয় Singleton!) প্রকৃতিতে।
রেটো মেয়ার এবং ডায়ান হ্যাকোবারের সাথে করেছিলেন যেখানে অ্যাপ্লিকেশন সাবক্লাসগুলির ব্যবহার সিঙ্গলটন নিদর্শনগুলির পক্ষে নিরুত্সাহিত করা হয়। সোমটিক আগে এই প্রকৃতির কিছু উল্লেখও করেছিল, যদিও আমি সেসময় এটি দেখিনি। অ্যান্ড্রয়েড প্ল্যাটফর্ম বজায় রাখতে রেটো এবং ডায়ান্নের ভূমিকার কারণে আমি তাদের বিশ্বাসকে অগ্রাহ্য করার পরামর্শ দিতে পারি না। তারা যা বলে, যায়। আমি অ্যাপ্লিকেশন সাবক্লাসের চেয়ে সিঙ্গেলটনকে অগ্রাধিকার দেওয়ার ক্ষেত্রে প্রকাশিত মতামতগুলির সাথে একমত হতে চাই না। আমার মতবিরোধে আমি সিঙ্গেলটন ডিজাইনের প্যাটার্নটির এই স্ট্যাক এক্সচেঞ্জের ব্যাখ্যায় সর্বোত্তমভাবে ধারণাগুলি ব্যবহার করব will একটি আকর্ষণীয় কথোপকথনটি নির্দেশ করার জন্য ডায়ারম্যান যথেষ্ট সদয় ছিলেন , যাতে আমাকে এই উত্তরে শর্তগুলি সংজ্ঞায়িত করতে না হয়। আমি চালিয়ে যাওয়ার আগে লিঙ্কটি স্কিমিংয়ে উত্সাহিত করি। বিস্তারিতভাবে:
ডায়ান বলেছেন, "অ্যাপ্লিকেশন থেকে সাবক্লাস করার কোনও কারণ নেই। এটি একটি সিঙ্গলটন তৈরির চেয়ে আলাদা নয় ..." এই প্রথম দাবিটি ভুল। এই জন্য দুটি প্রধান কারণ আছে। 1) অ্যাপ্লিকেশন বর্গটি কোনও অ্যাপ্লিকেশন বিকাশকারীর জন্য আরও ভাল আজীবন গ্যারান্টি সরবরাহ করে; এটির আবেদনের আজীবন গ্যারান্টি রয়েছে। একটি সিঙ্গলটন আবেদনের আজীবনের সাথে একচেটিয়াভাবে আবদ্ধ নয় (যদিও এটি কার্যকরভাবে রয়েছে)। এটি আপনার গড় অ্যাপ্লিকেশন বিকাশকারীদের জন্য একটি অ-ইস্যু হতে পারে তবে আমি যুক্তিটি বলতে চাই এটি ঠিক একই ধরণের অ্যান্ড্রয়েড এপিআইয়ের প্রস্তাব করা উচিত, এবং এটি এর সাথে সম্পর্কিত জীবনকাল হ্রাস করে অ্যান্ড্রয়েড সিস্টেমে আরও অনেক নমনীয়তা সরবরাহ করে ডেটা। ২) অ্যাপ্লিকেশন বর্গটি অ্যাপ্লিকেশন বিকাশকারীকে একক দৃষ্টান্ত ধারক সহ রাষ্ট্রের জন্য সরবরাহ করে, যা একক রাষ্ট্রের একক ধারক থেকে পৃথক। পার্থক্যের তালিকার জন্য উপরের সিঙ্গলটন ব্যাখ্যার লিঙ্কটি দেখুন।
ডায়ান এগিয়ে চলেছে, "... ভবিষ্যতে আপনার অনুশোচিত কিছু হওয়ার কারণ সম্ভবত আপনি যখন নিজের অ্যাপ্লিকেশন অবজেক্টটি স্বতন্ত্র অ্যাপ্লিকেশন যুক্তিযুক্ত হওয়া উচিত তখন এটির এই বিভ্রান্তিকর জঞ্জাল হয়ে উঠছে" " এটি অবশ্যই ভুল নয়, তবে এটি অ্যাপ্লিকেশন সাবক্লাসের উপরে সিঙ্গেলটন বেছে নেওয়ার কোনও কারণ নয়। ডায়ানের কোনও যুক্তিই যুক্তি সরবরাহ করে না যে একটি অ্যাপ্লিকেশন সাবক্লাসের চেয়ে সিঙ্গেলটন ব্যবহার করা ভাল, তিনি যে প্রতিষ্ঠানের চেষ্টা করেন তা হ'ল সিঙ্গলটন ব্যবহার করা কোনও অ্যাপ্লিকেশন সাবক্লাসের চেয়ে খারাপ নয়, যা আমি বিশ্বাস করি যে এটি মিথ্যা।
তিনি চালিয়ে যান, "এবং এটি আপনাকে আরও স্বাভাবিকভাবে নিয়ে যায় যে কীভাবে আপনার এই জিনিসগুলি পরিচালনা করা উচিত - চাহিদা অনুযায়ী সেগুলি শুরু করা।" এটি এই বিষয়টি উপেক্ষা করে যে আপনি কোনও অ্যাপ্লিকেশন সাবক্লাস ব্যবহার করে চাহিদা শুরু করতে পারবেন না এমন কোনও কারণ নেই। আবার কোনও পার্থক্য নেই।
ডায়ান দিয়ে শেষ হয় "ফ্রেমওয়ার্কটিতে অ্যাপ্লিকেশনটির জন্য রক্ষিত সমস্ত সামান্য ভাগ করা ডেটার জন্য প্রচুর সংখ্যক সিলেটলেট রয়েছে যেমন লোডযুক্ত সংস্থার ক্যাশে, অবজেক্টের পুল ইত্যাদি এটি দুর্দান্ত কাজ করে।" আমি যুক্তি দিচ্ছি না যে সিঙ্গলেটগুলি ব্যবহার করা ভাল কাজ করতে পারে না বা বৈধ বিকল্প নয়। আমি যুক্তি দিচ্ছি যে সিঙ্গললেটগুলি অ্যান্ড্রয়েড সিস্টেমের সাথে অ্যাপ্লিকেশন সাবক্লাস ব্যবহার করার মতো দৃ strong় চুক্তি সরবরাহ করে না এবং আরও বলে যে সিঙ্গলেটগুলি ব্যবহার করে সাধারণত অবিচ্ছেদ্য ডিজাইনের দিকে নির্দেশ করে, যা সহজেই সংশোধিত হয় না এবং রাস্তায় অনেক সমস্যার দিকে পরিচালিত করে। আইএমএইচও, অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলিকে অ্যান্ড্রয়েড এপিআই প্রস্তাবিত একটি শক্ত চুক্তি অ্যান্ড্রয়েডের সাথে প্রোগ্রামিংয়ের অন্যতম আকর্ষণীয় এবং আনন্দদায়ক দিক এবং এটি প্রাথমিক বিকাশকারীদের গ্রহণে সহায়তা করেছে যা অ্যান্ড্রয়েড প্ল্যাটফর্মটিকে আজকের সাফল্যের দিকে পরিচালিত করেছে।
ডায়ান নীচে পাশাপাশি মন্তব্য করেছে, অ্যাপ্লিকেশন সাবক্লাস ব্যবহার করার জন্য একটি অতিরিক্ত নেতিবাচক দিক উল্লেখ করেছে, তারা কম পারফরম্যান্স কোড লিখতে উত্সাহিত করতে বা সহজ করতে পারে। এটি খুব সত্য, এবং আমি এই উত্তরটি এখানে পারফ বিবেচনা করার গুরুত্বের উপর জোর দেওয়ার জন্য সম্পাদনা করেছি এবং আপনি যদি অ্যাপ্লিকেশন সাবক্লাসিং ব্যবহার করছেন তবে সঠিক পদ্ধতি গ্রহণ করা উচিত। ডায়ান বলেছেন যে, আপনার অ্যাপ্লিকেশন বর্গটি প্রতিবার আপনার প্রক্রিয়াটি লোড হওয়ার পরে ইনস্ট্যান্ট করা হবে (আপনার অ্যাপ্লিকেশন একাধিক প্রসেসে চালিত হলে একবারে একাধিকবার হতে পারে!) প্রক্রিয়াটি কেবল পটভূমির সম্প্রচারের জন্য লোড হচ্ছে কিনা তাও মনে রাখা গুরুত্বপূর্ণ ইভেন্ট। সুতরাং কোনও অ্যাপ্লিকেশন শ্রেণিকে কোনও প্রসেসিং করার জায়গার পরিবর্তে আপনার অ্যাপ্লিকেশনটির ভাগ করা উপাদানগুলিতে পয়েন্টারগুলির জন্য সংগ্রহস্থল হিসাবে আরও বেশি ব্যবহার করা গুরুত্বপূর্ণ!
পূর্ববর্তী স্ট্যাক এক্সচেঞ্জ লিঙ্ক থেকে চুরি হওয়া হিসাবে আমি আপনাকে সিঙ্গলটনে ডাউনসাইডগুলির নীচের তালিকাটি রেখে চলেছি:
- বিমূর্ত বা ইন্টারফেস ক্লাস ব্যবহারে অক্ষমতা;
- সাবক্লাসে অক্ষমতা;
- অ্যাপ্লিকেশন জুড়ে উচ্চ সংযুক্তকরণ (সংশোধন করা কঠিন);
- পরীক্ষা করা কঠিন (ইউনিট পরীক্ষায় জাল / উপহাস করতে পারবেন না);
- পরিবর্তনীয় অবস্থার ক্ষেত্রে সমান্তরাল হওয়া কঠিন (ব্যাপক লকিং প্রয়োজন);
এবং আমার নিজের যুক্ত করুন:
- অস্পষ্ট এবং অযৌক্তিক জীবনকালীন চুক্তি অ্যান্ড্রয়েড (বা অন্যান্য বেশিরভাগ) বিকাশের জন্য অসমর্থিত;