স্থিতিশীল অভ্যন্তর AsyncTask বর্গ কীভাবে ব্যবহার করবেন
ফাঁস রোধ করতে, আপনি অভ্যন্তর শ্রেণীর স্থির করতে পারেন। যদিও এর সাথে সমস্যাটি হ'ল কার্যকলাপের ইউআই ভিউ বা সদস্য ভেরিয়েবলগুলিতে আপনার আর অ্যাক্সেস নেই। আপনি একটি রেফারেন্সে পাস করতে পারেন Context
তবে তারপরে আপনি মেমরি ফাঁস হওয়ার একই ঝুঁকিটি চালান। (অ্যাসিঙ্কটাস্ক ক্লাসটির কাছে দৃ strong় উল্লেখ থাকলে অ্যান্ড্রয়েড ক্রিয়াকলাপ বন্ধ হয়ে যাওয়ার পরে তা সংগ্রহ করতে পারে না)) সমাধানটির ক্রিয়াকলাপে (বা আপনার যা Context
প্রয়োজন) দুর্বল উল্লেখ করা ।
public class MyActivity extends AppCompatActivity {
int mSomeMemberVariable = 123;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// start the AsyncTask, passing the Activity context
// in to a custom constructor
new MyTask(this).execute();
}
private static class MyTask extends AsyncTask<Void, Void, String> {
private WeakReference<MyActivity> activityReference;
// only retain a weak reference to the activity
MyTask(MyActivity context) {
activityReference = new WeakReference<>(context);
}
@Override
protected String doInBackground(Void... params) {
// do some long running task...
return "task finished";
}
@Override
protected void onPostExecute(String result) {
// get a reference to the activity if it is still there
MyActivity activity = activityReference.get();
if (activity == null || activity.isFinishing()) return;
// modify the activity's UI
TextView textView = activity.findViewById(R.id.textview);
textView.setText(result);
// access Activity member variables
activity.mSomeMemberVariable = 321;
}
}
}
মন্তব্য
- যতদূর আমি জানি, এই ধরণের মেমরি ফুটো বিপদটি সর্বদা সত্য, তবে আমি কেবল অ্যান্ড্রয়েড স্টুডিও 3.0 এ সতর্কতাটি দেখতে শুরু করেছি started অনেকগুলি মূল
AsyncTask
টিউটোরিয়াল এখনও এটির সাথে ডিল করে না (দেখুন এখানে , এখানে , এখানে এবং এখানে )।
- আপনি যদি
AsyncTask
শীর্ষ স্তরের শ্রেণি হন তবে আপনিও অনুরূপ পদ্ধতি অনুসরণ করবেন । একটি স্থিতিশীল অভ্যন্তর শ্রেণিটি মূলত জাভার শীর্ষ স্তরের শ্রেণির মতো।
আপনার যদি ক্রিয়াকলাপটি নিজেই প্রয়োজন না হয় তবে এখনও প্রসঙ্গে চান (উদাহরণস্বরূপ, একটি প্রদর্শন Toast
করতে), আপনি অ্যাপ্লিকেশন প্রসঙ্গে একটি রেফারেন্সে পাস করতে পারেন। এক্ষেত্রে AsyncTask
কনস্ট্রাক্টর এর মতো দেখতে পাবেন:
private WeakReference<Application> appReference;
MyTask(Application context) {
appReference = new WeakReference<>(context);
}
- এই সতর্কতাটিকে উপেক্ষা করার জন্য এবং কেবল অ-স্থিত শ্রেণীর ব্যবহারের জন্য কিছু যুক্তি রয়েছে। সর্বোপরি, অ্যাসিঙ্কটাস্কটি খুব স্বল্প সময়ের জন্য (দীর্ঘতম কয়েক সেকেন্ড) থাকার জন্য পরিকল্পনা করা হয়েছে এবং এটি যেভাবেই শেষ হবে না কেন এটি ক্রিয়াকলাপের সাথে তার রেফারেন্স প্রকাশ করবে। দেখুন এই এবং এই ।
- দুর্দান্ত নিবন্ধ: কীভাবে প্রসঙ্গে ফাঁস করবেন: হ্যান্ডলার এবং ইনার ক্লাসগুলি
Kotlin
কোটলিনে কেবল অভ্যন্তর শ্রেণীর কীওয়ার্ডটি অন্তর্ভুক্ত করবেন নাinner
। এটি এটি ডিফল্টরূপে স্থির করে তোলে।
class MyActivity : AppCompatActivity() {
internal var mSomeMemberVariable = 123
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// start the AsyncTask, passing the Activity context
// in to a custom constructor
MyTask(this).execute()
}
private class MyTask
internal constructor(context: MyActivity) : AsyncTask<Void, Void, String>() {
private val activityReference: WeakReference<MyActivity> = WeakReference(context)
override fun doInBackground(vararg params: Void): String {
// do some long running task...
return "task finished"
}
override fun onPostExecute(result: String) {
// get a reference to the activity if it is still there
val activity = activityReference.get()
if (activity == null || activity.isFinishing) return
// modify the activity's UI
val textView = activity.findViewById(R.id.textview)
textView.setText(result)
// access Activity member variables
activity.mSomeMemberVariable = 321
}
}
}