এখানে অ্যাসিঙ্কটাস্কের আরেকটি উদাহরণ যা Fragment
রানটাইম কনফিগারেশন পরিবর্তনগুলি (যখন ব্যবহারকারী স্ক্রিনটি ঘোরার সময় হিসাবে) পরিচালনা করতে ব্যবহার করে setRetainInstance(true)
। একটি নির্ধারিত (নিয়মিত আপডেট করা) অগ্রগতি বারটিও প্রদর্শিত হয়।
উদাহরণটি আংশিকভাবে অফিসিয়াল ডক্সের উপর ভিত্তি করে তৈরি করা হয়েছে, একটি কনফিগারেশন চেঞ্জ চলাকালীন কোনও অবজেক্ট ধরে রাখা ।
এই উদাহরণে ব্যাকগ্রাউন্ড থ্রেডের প্রয়োজনীয় কাজের কাজটি হ'ল ইন্টারনেট থেকে ইউআইতে কোনও চিত্র লোড করা।
অ্যালেক্স লকউড ঠিক বলে মনে হয় যে অসিঙ্কটাস্কের সাথে "রিটেইনড ফ্রেগমেন্ট" ব্যবহার করে রানটাইম কনফিগারেশন পরিবর্তনগুলি পরিচালনা করার ক্ষেত্রে এটি সর্বোত্তম অনুশীলন। onRetainNonConfigurationInstance()
অ্যান্ড্রয়েড স্টুডিওতে লিন্টে অবহেলিত হয়। অফিসিয়াল ডকস নিজেকে কনফিগারেশন চেঞ্জ হ্যান্ডলিংandroid:configChanges
থেকে , ...
কনফিগারেশন পরিবর্তনটি নিজেকে পরিচালনা করা বিকল্প সংস্থানগুলি ব্যবহার করা আরও বেশি জটিল করে তুলতে পারে, কারণ সিস্টেমগুলি সেগুলি স্বয়ংক্রিয়ভাবে আপনার জন্য প্রয়োগ করে না। কোনও কনফিগারেশন পরিবর্তনের কারণে আপনাকে পুনরায় আরম্ভ করা এড়াতে হবে এবং বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য প্রস্তাবিত না হলে এই কৌশলটি সর্বশেষ অবলম্বন হিসাবে বিবেচনা করা উচিত।
তারপরে পটভূমির থ্রেডের জন্য কোনও একটি এ্যাসিনটাস্ক ব্যবহার করা উচিত কিনা তা নিয়ে সমস্যা রয়েছে is
AsyncTask জন্য অফিসিয়াল রেফারেন্স সতর্ক ...
অ্যাসিঙ্কটাস্কগুলি আদর্শভাবে সংক্ষিপ্ত ক্রিয়াকলাপের জন্য ব্যবহার করা উচিত (সর্বাধিক কয়েক সেকেন্ড) threads এক্সিকিউটার, থ্রেডপুলএক্সেকিউটার এবং ফিউচারটাস্ক।
বিকল্পভাবে কেউ অ্যাসিক্রোনাস ক্রিয়াকলাপ সম্পাদনের জন্য কোনও পরিষেবা, লোডার (একটি কার্সারলডার বা অ্যাসিঙ্কটাস্কলডার ব্যবহার করে) বা সামগ্রী সরবরাহকারী ব্যবহার করতে পারে।
আমি বাকি পোস্টগুলিকে এতে ভাঙ্গি:
- কার্যপ্রণালী; এবং
- উপরোক্ত পদ্ধতির জন্য সমস্ত কোড।
কার্যপ্রণালী
কোনও ক্রিয়াকলাপের অভ্যন্তর শ্রেণি হিসাবে বেসিক অ্যাসিঙ্কটাস্ক দিয়ে শুরু করুন (এটি কোনও অভ্যন্তরীণ শ্রেণির হওয়ার দরকার নেই তবে এটি সম্ভবত সুবিধাজনক হবে)। এই পর্যায়ে AsyncTask রানটাইম কনফিগারেশন পরিবর্তনগুলি পরিচালনা করে না।
public class ThreadsActivity extends ActionBarActivity {
private ImageView mPictureImageView;
private class LoadImageFromNetworkAsyncTask
extends AsyncTask<String, Void, Bitmap> {
@Override
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
mPictureImageView.setImageBitmap(bitmap);
}
}
/**
* Requires in AndroidManifext.xml
* <uses-permission android:name="android.permission.INTERNET" />
*/
private Bitmap loadImageFromNetwork(String url) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream((InputStream)
new URL(url).getContent());
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_threads);
mPictureImageView =
(ImageView) findViewById(R.id.imageView_picture);
}
public void getPicture(View view) {
new LoadImageFromNetworkAsyncTask()
.execute("http://i.imgur.com/SikTbWe.jpg");
}
}
ফ্রেসমেন্ট শ্রেণি প্রসারিত এবং এর নিজস্ব ইউআই নেই এমন একটি নেস্টেড ক্লাসের রেটিন্টফ্র্যাগমেন্ট যুক্ত করুন। এই খণ্ডটির অনক্রিট ইভেন্টে সেটট্রেইটইন ইনস্ট্যান্স (সত্য) যুক্ত করুন। আপনার ডেটা সেট এবং পেতে পদ্ধতি সরবরাহ করুন।
public class ThreadsActivity extends Activity {
private ImageView mPictureImageView;
private RetainedFragment mRetainedFragment = null;
...
public static class RetainedFragment extends Fragment {
private Bitmap mBitmap;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The key to making data survive
// runtime configuration changes.
setRetainInstance(true);
}
public Bitmap getData() {
return this.mBitmap;
}
public void setData(Bitmap bitmapToRetain) {
this.mBitmap = bitmapToRetain;
}
}
private class LoadImageFromNetworkAsyncTask
extends AsyncTask<String, Integer,Bitmap> {
....
বহিরাগত কার্যকলাপের ক্লাসের অনক্রিট () রেটিনফ্রেগমেন্টটি হ্যান্ডেল করুন: যদি ইতিমধ্যে এটি উপস্থিত থাকে (যদি কার্যকলাপটি পুনরায় চালু হয় তবে) এটি উল্লেখ করুন; এটি উপস্থিত না থাকলে এটি তৈরি এবং যুক্ত করুন; তারপরে, এটি ইতিমধ্যে বিদ্যমান থাকলে, রেটিনফ্র্যাগমেন্ট থেকে ডেটা পান এবং সেই ডেটা দিয়ে আপনার ইউআই সেট করুন।
public class ThreadsActivity extends Activity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_threads);
final String retainedFragmentTag = "RetainedFragmentTag";
mPictureImageView =
(ImageView) findViewById(R.id.imageView_picture);
mLoadingProgressBar =
(ProgressBar) findViewById(R.id.progressBar_loading);
// Find the RetainedFragment on Activity restarts
FragmentManager fm = getFragmentManager();
// The RetainedFragment has no UI so we must
// reference it with a tag.
mRetainedFragment =
(RetainedFragment) fm.findFragmentByTag(retainedFragmentTag);
// if Retained Fragment doesn't exist create and add it.
if (mRetainedFragment == null) {
// Add the fragment
mRetainedFragment = new RetainedFragment();
fm.beginTransaction()
.add(mRetainedFragment, retainedFragmentTag).commit();
// The Retained Fragment exists
} else {
mPictureImageView
.setImageBitmap(mRetainedFragment.getData());
}
}
ইউআই থেকে অ্যাসিঙ্কটাস্ক শুরু করুন
public void getPicture(View view) {
new LoadImageFromNetworkAsyncTask().execute(
"http://i.imgur.com/SikTbWe.jpg");
}
একটি নির্ধারিত অগ্রগতি বার যুক্ত করুন এবং কোড করুন:
- ইউআই লেআউটে একটি অগ্রগতি বার যুক্ত করুন;
- ক্রিয়াকলাপের ক্রিয়াকলাপে এটির একটি রেফারেন্স পান ();
- প্রক্রিয়াটির শুরু এবং শেষে এটিকে দৃশ্যমান এবং অদৃশ্য করে তুলুন;
- অনপ্রযুক্তি আপডেটে UI তে রিপোর্ট করার অগ্রগতিটি সংজ্ঞায়িত করুন।
- অ্যাসিঙ্কটাস্ক ২ য় জেনেরিক প্যারামিটারটি শূন্য থেকে একটি প্রকারে পরিবর্তন করুন যা অগ্রগতি আপডেটগুলি হ্যান্ডেল করতে পারে (যেমন পূর্ণসংখ্যার)।
- ডাইনব্যাকগ্রাউন্ডে () এর নিয়মিত পয়েন্টগুলিতে প্রকাশের প্রচার।
উপরোক্ত পদ্ধতির জন্য সমস্ত কোড
ক্রিয়াকলাপ বিন্যাস
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.mysecondapp.ThreadsActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<ImageView
android:id="@+id/imageView_picture"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="@android:color/black" />
<Button
android:id="@+id/button_get_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/imageView_picture"
android:onClick="getPicture"
android:text="Get Picture" />
<Button
android:id="@+id/button_clear_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/button_get_picture"
android:layout_toEndOf="@id/button_get_picture"
android:layout_toRightOf="@id/button_get_picture"
android:onClick="clearPicture"
android:text="Clear Picture" />
<ProgressBar
android:id="@+id/progressBar_loading"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/button_get_picture"
android:progress="0"
android:indeterminateOnly="false"
android:visibility="invisible" />
</RelativeLayout>
</ScrollView>
এর সাথে ক্রিয়াকলাপ: উপ-শ্রেণিবদ্ধ AsyncTask অভ্যন্তর শ্রেণি; সাবক্ল্যাসড রিটইনফ্রেগমেন্ট অভ্যন্তর শ্রেণি যা রানটাইম কনফিগারেশন পরিবর্তনগুলি পরিচালনা করে (উদাহরণস্বরূপ যখন ব্যবহারকারী স্ক্রিনটি ঘোরান); এবং নিয়মিত বিরতিতে অগ্রগতি বার আপডেট করা নির্ধারণ করে। ...
public class ThreadsActivity extends Activity {
private ImageView mPictureImageView;
private RetainedFragment mRetainedFragment = null;
private ProgressBar mLoadingProgressBar;
public static class RetainedFragment extends Fragment {
private Bitmap mBitmap;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The key to making data survive runtime configuration changes.
setRetainInstance(true);
}
public Bitmap getData() {
return this.mBitmap;
}
public void setData(Bitmap bitmapToRetain) {
this.mBitmap = bitmapToRetain;
}
}
private class LoadImageFromNetworkAsyncTask extends AsyncTask<String,
Integer, Bitmap> {
@Override
protected Bitmap doInBackground(String... urls) {
// Simulate a burdensome load.
int sleepSeconds = 4;
for (int i = 1; i <= sleepSeconds; i++) {
SystemClock.sleep(1000); // milliseconds
publishProgress(i * 20); // Adjust for a scale to 100
}
return com.example.standardapplibrary.android.Network
.loadImageFromNetwork(
urls[0]);
}
@Override
protected void onProgressUpdate(Integer... progress) {
mLoadingProgressBar.setProgress(progress[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
publishProgress(100);
mRetainedFragment.setData(bitmap);
mPictureImageView.setImageBitmap(bitmap);
mLoadingProgressBar.setVisibility(View.INVISIBLE);
publishProgress(0);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_threads);
final String retainedFragmentTag = "RetainedFragmentTag";
mPictureImageView = (ImageView) findViewById(R.id.imageView_picture);
mLoadingProgressBar = (ProgressBar) findViewById(R.id.progressBar_loading);
// Find the RetainedFragment on Activity restarts
FragmentManager fm = getFragmentManager();
// The RetainedFragment has no UI so we must reference it with a tag.
mRetainedFragment = (RetainedFragment) fm.findFragmentByTag(
retainedFragmentTag);
// if Retained Fragment doesn't exist create and add it.
if (mRetainedFragment == null) {
// Add the fragment
mRetainedFragment = new RetainedFragment();
fm.beginTransaction().add(mRetainedFragment,
retainedFragmentTag).commit();
// The Retained Fragment exists
} else {
mPictureImageView.setImageBitmap(mRetainedFragment.getData());
}
}
public void getPicture(View view) {
mLoadingProgressBar.setVisibility(View.VISIBLE);
new LoadImageFromNetworkAsyncTask().execute(
"http://i.imgur.com/SikTbWe.jpg");
}
public void clearPicture(View view) {
mRetainedFragment.setData(null);
mPictureImageView.setImageBitmap(null);
}
}
এই উদাহরণে লাইব্রেরির ফাংশন (উপরে বর্ণিত স্পষ্ট প্যাকেজ উপসর্গ com.example.standardapplibrary.android.Network সহ) যা সত্য কাজ করে ...
public static Bitmap loadImageFromNetwork(String url) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream((InputStream) new URL(url)
.getContent());
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
আপনার ব্যাকগ্রাউন্ড টাস্কের যে কোনও অনুমতি AndroidManLive.xML এ যুক্ত করুন ...
<manifest>
...
<uses-permission android:name="android.permission.INTERNET" />
আপনার ক্রিয়াকলাপটি AndroidManLive.xML এ যুক্ত করুন ...
<manifest>
...
<application>
<activity
android:name=".ThreadsActivity"
android:label="@string/title_activity_threads"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.mysecondapp.MainActivity" />
</activity>