স্ক্রিন রোটেশনের সময় কীভাবে একটি অ্যাসিঙ্কটাস্ক পরিচালনা করবেন?


88

আমি কীভাবে আমার দৃষ্টান্তের অবস্থাটি সংরক্ষণ করব বা স্ক্রিন রোটেশনের সময় আমার ক্রিয়াকলাপ ধ্বংস হওয়ার সাথে কীভাবে মোকাবিলা করব সে সম্পর্কে আমি অনেক কিছু পড়েছি।

অনেকগুলি সম্ভাবনা রয়েছে বলে মনে হচ্ছে তবে অ্যাসিঙ্কটাস্কের ফলাফল পুনরুদ্ধারের জন্য কোনটি সবচেয়ে ভাল কাজ করে তা আমি খুঁজে পাইনি।

আমার কাছে কিছু অ্যাসিঙ্কটাস রয়েছে যা কেবল আবার শুরু হয়েছে এবং isFinishing()ক্রিয়াকলাপটির পদ্ধতিটি কল করে এবং যদি ক্রিয়াকলাপ শেষ হয় তবে তারা কিছু আপডেট করবে না।

সমস্যাটি হ'ল আমার কাছে একটি টাস্ক রয়েছে যা একটি ওয়েব পরিষেবাতে অনুরোধ করে যা ব্যর্থ বা সফল হতে পারে এবং টাস্কটি পুনরায় চালু করা ব্যবহারকারীর জন্য আর্থিক ক্ষতির কারণ হতে পারে।

কীভাবে সমাধান করবেন? সম্ভাব্য সমাধানগুলির সুবিধা বা অসুবিধাগুলি কী কী?


4
আমার উত্তর এখানে দেখুনআসলে কীsetRetainInstance(true) উপকারী তা সম্পর্কে আপনি এই তথ্যটিও পেতে পারেন।
টিমম্মে

আমি যা করব তা হ'ল একটি স্থানীয় পরিষেবা কার্যকর করা যা আপনার অ্যাসিঙ্কটাস্ক করছে এমন প্রক্রিয়াকরণ (থ্রেডে) সম্পাদন করে। ফলাফলগুলি প্রদর্শন করতে, আপনার ক্রিয়াকলাপে ডেটা সম্প্রচার করুন। এখন কার্যকলাপটি কেবলমাত্র ডেটা দেখানোর জন্য দায়ী এবং কোনও পর্দা ঘোরার মাধ্যমে প্রসেসিং কখনও বাধাগ্রস্থ হয় না
কেউ কেউ কোথাও

AsyncTask এর পরিবর্তে AsyncTaskLoader ব্যবহার সম্পর্কে কী ??
সৌরংশু বিশ্বাস

উত্তর:


6

আমার প্রথম পরামর্শটি হ'ল আপনার পর্দার ঘূর্ণায়মান (ডিফল্ট আচরণ) পুনরায় সেট করতে আপনার কার্যকলাপটি আসলে প্রয়োজন তা নিশ্চিত করা to <activity>যতবারই আমার ঘূর্ণনের সমস্যা হয়েছে আমি এই বৈশিষ্ট্যটি আমার ট্যাগে অ্যান্ড্রয়েড ম্যানিফেস্ট.এক্সএমএলে যুক্ত করেছি এবং ঠিক হয়েছি ।

android:configChanges="keyboardHidden|orientation"

এটি অদ্ভুত দেখাচ্ছে, তবে এটি আপনার onConfigurationChanged()পদ্ধতির সাথে কী তা বন্ধ করে দেয় , আপনি যদি এটি সরবরাহ না করেন তবে এটি বিন্যাসটি পুনরায় পরিমাপ করা ব্যতীত অন্য কিছুই করেন না, যা বেশিরভাগ সময় ঘোরানো পরিচালনা করার উপযুক্ত উপায় বলে মনে হয় perfectly ।


4
তবে এটি ক্রিয়াকলাপটি বিন্যাস পরিবর্তন করতে বাধা দেবে। এবং তাই ব্যবহারকারীকে তার অ্যাপ্লিকেশন দ্বারা নির্ধারিত একটি নির্দিষ্ট অভিযোজনে তার ডিভাইসগুলি তার প্রয়োজনগুলি অনুসারে ব্যবহার করতে বাধ্য করে।
জানুজ্জ

77
এই কৌশলটি ব্যবহার করা আপনাকে কনফিগারেশনের নির্দিষ্ট সংস্থানগুলি সহজে ব্যবহার থেকে বিরত রাখে। উদাহরণস্বরূপ, আপনি যদি নিজের বিন্যাস বা অঙ্কনযোগ্য বা স্ট্রিং বা পোর্ট্রেট এবং ল্যান্ডস্কেপে আলাদা হতে চান তবে আপনি ডিফল্ট আচরণ চান। কনফিগার চেঞ্জটি ওভাররাইড করা খুব নির্দিষ্ট ক্ষেত্রে (একটি গেম, একটি ওয়েব ব্রাউজার ইত্যাদি) করা উচিত এবং অলসতা বা সুবিধার বাইরে নয় কারণ আপনি নিজেকে সীমাবদ্ধ করছেন।
রোমেন গাই

38
ঠিক আছে, রোমেন। "আপনি যদি নিজের লেআউট, অঙ্কনযোগ্য বা স্ট্রিং বা পোর্ট্রেট এবং ল্যান্ডস্কেপে আলাদা কিছু হতে চান তবে আপনি পূর্বনির্ধারিত আচরণ চান", আমি বিশ্বাস করি যে এটি আপনার অনুমানের চেয়ে অনেক বিরল ব্যবহারের ঘটনা। আপনি যাকে "খুব সুনির্দিষ্ট ক্ষেত্রে" বলে থাকেন তা আমার বিশ্বাস অধিকাংশ বিকাশকারী। সমস্ত মাত্রায় কাজ করে এমন আপেক্ষিক লেআউট ব্যবহার করা সেরা অনুশীলন এবং এটি এতটা কঠিন নয়। আলস্য কথাবার্তা অত্যন্ত বিপথগামী, এই কৌশলগুলি ব্যবহারকারীর অভিজ্ঞতা উন্নয়নের জন্য বিকাশের সময় হ্রাস না করে।
জিম ব্ল্যাকার

4
আমি খুঁজে পেয়েছি যে এটি লিনিয়ারলআউটের জন্য নিখুঁত কাজ করে, তবে রিলেটিভলআউট ব্যবহার করার সময় ল্যান্ডস্কেপ মোডে স্যুইচ করার সময় এটি বিন্যাসটি সঠিকভাবে পুনরায় আঁকবে না (কমপক্ষে এন 1 এ নয়)। : এই প্রশ্ন দেখুন stackoverflow.com/questions/2987049/...
JohnRock

9
আমি রোমেনের সাথে একমত (তিনি জানেন যে তিনি কী বিষয়ে কথা বলছেন, তিনি ওএস বিকাশ করেছেন)। আপনি যখন কোনও ট্যাবলেটে আপনার অ্যাপ্লিকেশনটি পোর্ট করতে চান এবং প্রসারিত হয়ে গেলে আপনার ইউআই ভয়ঙ্কর দেখায় তখন কী ঘটে? আপনি যদি এই উত্তরের পন্থা অবলম্বন করেন তবে আপনাকে আপনার সম্পূর্ণ সমাধানটি পুনরুদ্ধার করতে হবে কারণ আপনি এই অলস হ্যাকটি নিয়ে গেছেন।
অস্টিন মাহুনি

46

আমি কীভাবে কোড . google.com/p/shelvesAsyncTask এ ওরিয়েন্টেশন পরিবর্তনগুলি পরিচালনা করব তা পরীক্ষা করে দেখতে পারেন । এটি করার বিভিন্ন উপায় রয়েছে, আমি এই অ্যাপ্লিকেশনটিতে যেটি বেছে নিয়েছি তা হ'ল বর্তমানে চলমান কোনও কাজ বাতিল করা, তার রাজ্যটি সংরক্ষণ করা এবং নতুন তৈরি হওয়ার সময় সেভ স্টেট দিয়ে একটি নতুন শুরু করা । এটি করা সহজ, এটি ভালভাবে কাজ করে এবং বোনাস হিসাবে ব্যবহারকারী যখন অ্যাপটি ছেড়ে যায় তখন এটি আপনার কাজগুলি বন্ধ করার যত্ন নেয়।Activity

এছাড়াও আপনি ব্যবহার করতে পারেন onRetainNonConfigurationInstance()আপনার পাস AsyncTaskনতুন Activity(পূর্ববর্তী লিক না সম্পর্কে সতর্কতা অবলম্বন করা আবশ্যক Activityএই ভাবে যদিও।)


4
আমি এটি চেষ্টা করেছিলাম এবং বই অনুসন্ধানের
বিঘ্নের সময় ঘোরছিলাম

4
আমি সেই কোডটিতে অ্যাসিঙ্কটাস্কের একটিও ব্যবহার খুঁজে পাইনি। এখানে একটি ক্লাসের ইউজারটাইজ রয়েছে যা দেখতে দেখতে একই রকম। এই প্রকল্পটি কি অ্যাসিঙ্কটাস্কের পূর্বাভাস দেয়?
ডেভনসোল

7
অ্যাসিঙ্কটাস্ক ইউজারটাস্ক থেকে এসেছে। আমি প্রথমে আমার নিজস্ব অ্যাপ্লিকেশনগুলির জন্য ইউজারটাস্ক লিখেছি এবং পরে এ্যাসিঙ্কটাসকে পরিণত করেছি। দুঃখিত যে আমি ভুলে গিয়েছিলাম এটির নামকরণ হয়েছে।
রোমেন গাই

@ রোমেনগুই হাই, আশা করি আপনি ভাল আছেন। আপনার কোড অনুসারে 2 টি অনুরোধ সার্ভারে প্রেরণ করা হলেও প্রথম কাজটি বাতিল হলেও এটি সফলভাবে বাতিল হয়নি। কেন জানি না। আপনি কি দয়া করে আমাকে বলবেন এটি সমাধান করার কোনও উপায় আছে।
iamcrypticcoder

10

এটি অ্যান্ড্রয়েড সম্পর্কিত আমি সবচেয়ে আকর্ষণীয় প্রশ্ন !!! আসলে আমি গত মাসগুলিতে ইতিমধ্যে সমাধানটি সন্ধান করেছি। এখনও সমাধান হয়নি।

সতর্কতা অবলম্বন করুন, কেবলমাত্র ওভাররাইড করে

android:configChanges="keyboardHidden|orientation"

স্টাফ যথেষ্ট নয়।

আপনার অ্যাসিঙ্কটাস চলাকালীন যখন ব্যবহারকারী কোনও ফোন কল পান তখন কেসটি বিবেচনা করুন। আপনার অনুরোধটি ইতিমধ্যে সার্ভার দ্বারা প্রক্রিয়া করা হচ্ছে, সুতরাং AsyncTask প্রতিক্রিয়ার জন্য অপেক্ষা করছে। এই মুহুর্তে আপনার অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে চলেছে, কারণ ফোন অ্যাপ্লিকেশনটি সবেমাত্র সম্মুখভাগে এসেছে। ওএস আপনার ক্রিয়াকলাপটিকে পটভূমির মধ্যে থেকে হত্যা করতে পারে।


6

কেন আপনি সর্বদা অ্যান্ড্রয়েড দ্বারা সরবরাহিত সিঙ্গলটনে বর্তমান অ্যাসিঙ্কটাসকের কোনও উল্লেখ রাখেন না?

যখনই কোনও কাজ শুরু হয়, প্রি এক্সেকসুট বা বিল্ডারে, আপনি সংজ্ঞা দিন:

((Application) getApplication()).setCurrentTask(asyncTask);

যখনই এটি শেষ হয় আপনি এটিকে বাতিল করে দিন set

এইভাবে আপনার কাছে সর্বদা একটি রেফারেন্স থাকে যা আপনাকে আপনার নির্দিষ্ট যুক্তির জন্য বরাদ্দকৃত, অনক্রিট বা অন রেসুমির মতো কিছু করতে দেয়:

this.asyncTaskReference = ((Application) getApplication()).getCurrentTask();

যদি এটি নাল হয় তবে আপনি জানেন যে বর্তমানে কোনটিই চলছে না!

:-)


এই কাজ করবে? কেউ কি এই পরীক্ষা করেছে? যদি কোনও ফোন কল বাধা ঘটে বা যদি আমরা একটি নতুন ক্রিয়াকলাপে নেভিগেট করে আবার ফিরে যাই তবে কী কাজটি সিস্টেমের দ্বারা এখনও মারা যাবে?
রবার্ট

6
Applicationউদাহরণস্বরূপ তার নিজস্ব জীবনচক্র রয়েছে - এটি ওএস দ্বারাও মেরে ফেলা যায়, সুতরাং এই সমাধানটি একটি হার্ড-টু-প্রজনন বাগের কারণ হতে পারে।
ভিট খুডেনকো

7
আমি ভেবেছিলাম: যদি অ্যাপ্লিকেশনটি মারা যায়, পুরো অ্যাপ্লিকেশনটি মারা যায় (এবং এইভাবে, সমস্ত এসিঙ্কটাস্কগুলিও)?
মানমাল

আমি মনে করি যে অ্যাপ্লিকেশনটি সমস্ত অ্যাসিনটাস্কগুলি (খুব বিরল) না করে হত্যা করা যেতে পারে। তবে @ প্রতিটি অ্যাসিঙ্কটাস্কের শুরু এবং শেষের দিকে কিছু সহজ করণীয় যাচাইকরণের সাহায্যে আপনি বাগগুলি এড়াতে পারবেন।
neteinstein

5

এর সর্বাধিক সঠিক উপায় হ'ল ঘোরাঘুরির উপরে অ্যাসিঙ্ক টাস্কটি ধরে রাখার জন্য একটি খণ্ড ব্যবহার করা।

আপনার অ্যাপগুলিতে এই কৌশলটি ইন্টিগ্রেটেডটিকে অনুসরণ করা সহজ করে তোলে এমন খুব সাধারণ উদাহরণের একটি লিঙ্ক এখানে।

https://gist.github.com/daichan4649/2480065


এখানে আরও একটি টিউটোরিয়াল যা রক্ষিত টুকরো টুকরোটি
২০১০


3

আমার দৃষ্টিতে, onRetainNonConfigurationInstanceবর্তমান ক্রিয়াকলাপের অবজেক্ট থেকে ডিকম্পলিংয়ের মাধ্যমে অ্যাসিঙ্কটাক সংরক্ষণ করা এবং ওরিয়েন্টেশন পরিবর্তনের পরে এটি কোনও নতুন ক্রিয়াকলাপের সাথে বাঁধাই করা ভাল। এখানে আমি অসিঙ্কটাস্ক এবং প্রগ্রেসডায়ালগের সাথে কীভাবে কাজ করব তার একটি খুব সুন্দর উদাহরণ পেয়েছি।


2

অ্যান্ড্রয়েড: কনফিগারেশন পরিবর্তনের সাথে ব্যাকগ্রাউন্ড প্রসেসিং / অ্যাসিঙ্ক ওপেনশন

পটভূমি প্রক্রিয়া চলাকালীন async প্রচ্ছন্নতার রাজ্যগুলি বজায় রাখতে: আপনি খণ্ডগুলির সাহায্য নিতে পারেন।

নিম্নলিখিত পদক্ষেপ দেখুন:

পদক্ষেপ 1: একটি শিরোনামহীন খণ্ড তৈরি করুন ব্যাকগ্রাউন্ড টাস্কটি বলতে দিন এবং এটিতে একটি বেসরকারী এসিঙ্ক টাস্ক ক্লাস যুক্ত করুন।

পদক্ষেপ 2 (Stepচ্ছিক পদক্ষেপ): আপনি যদি আপনার ক্রিয়াকলাপের উপরে লোডিং কার্সারটি কোডের নীচে ব্যবহার করতে চান তবে:

পদক্ষেপ 3: আপনার মূল ক্রিয়াকলাপে ব্যাকগ্রাউন্ড টাস্কক্যালব্যাক্স ইন্টারফেসটি পদক্ষেপ 1 এ সংজ্ঞায়িত করা হয়েছে

class BackgroundTask extends Fragment {
public BackgroundTask() {

}

// Add a static interface 

static interface BackgroundTaskCallbacks {
    void onPreExecute();

    void onCancelled();

    void onPostExecute();

    void doInBackground();
}

private BackgroundTaskCallbacks callbacks;
private PerformAsyncOpeation asyncOperation;
private boolean isRunning;
private final String TAG = BackgroundTask.class.getSimpleName();

/**
 * Start the async operation.
 */
public void start() {
    Log.d(TAG, "********* BACKGROUND TASK START OPERATION ENTER *********");
    if (!isRunning) {
        asyncOperation = new PerformAsyncOpeation();
        asyncOperation.execute();
        isRunning = true;
    }
    Log.d(TAG, "********* BACKGROUND TASK START OPERATION EXIT *********");
}

/**
 * Cancel the background task.
 */
public void cancel() {
    Log.d(TAG, "********* BACKGROUND TASK CANCEL OPERATION ENTER *********");
    if (isRunning) {
        asyncOperation.cancel(false);
        asyncOperation = null;
        isRunning = false;
    }
    Log.d(TAG, "********* BACKGROUND TASK CANCEL OPERATION EXIT *********");
}

/**
 * Returns the current state of the background task.
 */
public boolean isRunning() {
    return isRunning;
}

/**
 * Android passes us a reference to the newly created Activity by calling
 * this method after each configuration change.
 */
public void onAttach(Activity activity) {
    Log.d(TAG, "********* BACKGROUND TASK ON ATTACH ENTER *********");
    super.onAttach(activity);
    if (!(activity instanceof BackgroundTaskCallbacks)) {
        throw new IllegalStateException(
                "Activity must implement the LoginCallbacks interface.");
    }

    // Hold a reference to the parent Activity so we can report back the
    // task's
    // current progress and results.
    callbacks = (BackgroundTaskCallbacks) activity;
    Log.d(TAG, "********* BACKGROUND TASK ON ATTACH EXIT *********");
}

public void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "********* BACKGROUND TASK ON CREATE ENTER *********");
    super.onCreate(savedInstanceState);
    // Retain this fragment across configuration changes.
    setRetainInstance(true);
    Log.d(TAG, "********* BACKGROUND TASK ON CREATE EXIT *********");
}

public void onDetach() {
    super.onDetach();
    callbacks = null;
}

private class PerformAsyncOpeation extends AsyncTask<Void, Void, Void> {
    protected void onPreExecute() {
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > ON PRE EXECUTE ENTER *********");
        if (callbacks != null) {
            callbacks.onPreExecute();
        }
        isRunning = true;
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > ON PRE EXECUTE EXIT *********");
    }

    protected Void doInBackground(Void... params) {
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > DO IN BACKGROUND ENTER *********");
        if (callbacks != null) {
            callbacks.doInBackground();
        }
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > DO IN BACKGROUND EXIT *********");
        return null;
    }

    protected void onCancelled() {
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > ON CANCEL ENTER *********");
        if (callbacks != null) {
            callbacks.onCancelled();
        }
        isRunning = false;
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > ON CANCEL EXIT *********");
    }

    protected void onPostExecute(Void ignore) {
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > ON POST EXECUTE ENTER *********");
        if (callbacks != null) {
            callbacks.onPostExecute();
        }
        isRunning = false;
        Log.d(TAG,
                "********* BACKGROUND TASK :-> ASYNC OPERATION :- > ON POST EXECUTE EXIT *********");
    }
}

public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setRetainInstance(true);
}

public void onStart() {
    super.onStart();
}

public void onResume() {
    super.onResume();
}

public void onPause() {
    super.onPause();
}

public void onStop() {
    super.onStop();
}

public class ProgressIndicator extends Dialog {

public ProgressIndicator(Context context, int theme) {
    super(context, theme);
}

private ProgressBar progressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.progress_indicator);
    this.setCancelable(false);
    progressBar = (ProgressBar) findViewById(R.id.progressBar);
    progressBar.getIndeterminateDrawable().setColorFilter(R.color.DarkBlue, android.graphics.PorterDuff.Mode.SCREEN);
}

@Override
public void show() {
    super.show();
}

@Override
public void dismiss() {
    super.dismiss();
}

@Override
public void cancel() {
    super.cancel();
}

public class MyActivity extends FragmentActivity implements BackgroundTaskCallbacks,{

private static final String KEY_CURRENT_PROGRESS = "current_progress";

ProgressIndicator progressIndicator = null;

private final static String TAG = MyActivity.class.getSimpleName();

private BackgroundTask task = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(//"set your layout here");
    initialize your views and widget here .............



    FragmentManager fm = getSupportFragmentManager();
    task = (BackgroundTask) fm.findFragmentByTag("login");

    // If the Fragment is non-null, then it is currently being
    // retained across a configuration change.
    if (task == null) {
        task = new BackgroundTask();
        fm.beginTransaction().add(task, "login").commit();
    }

    // Restore saved state
    if (savedInstanceState != null) {
        Log.i(TAG, "KEY_CURRENT_PROGRESS_VALUE ON CREATE :: "
                + task.isRunning());
        if (task.isRunning()) {
            progressIndicator = new ProgressIndicator(this,
                    R.style.TransparentDialog);
            if (progressIndicator != null) {
                progressIndicator.show();
            }
        }
    }
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();

}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // save the current state of your operation here by saying this 

    super.onSaveInstanceState(outState);
    Log.i(TAG, "KEY_CURRENT_PROGRESS_VALUE ON SAVE INSTANCE :: "
            + task.isRunning());
    outState.putBoolean(KEY_CURRENT_PROGRESS, task.isRunning());
    if (progressIndicator != null) {
        progressIndicator.dismiss();
        progressIndicator.cancel();
    }
    progressIndicator = null;
}


private void performOperation() {

            if (!task.isRunning() && progressIndicator == null) {
                progressIndicator = new ProgressIndicator(this,
                        R.style.TransparentDialog);
                progressIndicator.show();
            }
            if (task.isRunning()) {
                task.cancel();
            } else {
                task.start();
            }
        }


@Override
protected void onDestroy() {
    super.onDestroy();
    if (progressIndicator != null) {
        progressIndicator.dismiss();
        progressIndicator.cancel();
    }
    progressIndicator = null;
}

@Override
public void onPreExecute() {
    Log.i(TAG, "CALLING ON PRE EXECUTE");
}

@Override
public void onCancelled() {
    Log.i(TAG, "CALLING ON CANCELLED");
    if (progressIndicator != null) {
        progressIndicator.dismiss();
        progressIndicator.cancel();

}

public void onPostExecute() {
    Log.i(TAG, "CALLING ON POST EXECUTE");
    if (progressIndicator != null) {
        progressIndicator.dismiss();
        progressIndicator.cancel();
        progressIndicator = null;
    }
}

@Override
public void doInBackground() {
    // put your code here for background operation
}

}


1

একটি বিষয় বিবেচনা করার বিষয় হ'ল AsyncTask এর ফলাফলটি কেবল সেই ক্রিয়াকলাপের জন্য পাওয়া উচিত যা কাজটি শুরু করেছিল। যদি হ্যাঁ, তবে রোমেন গাইয়ের উত্তরটি সবচেয়ে ভাল। এটি যদি আপনার অ্যাপ্লিকেশনটির অন্যান্য ক্রিয়াকলাপের জন্য উপলব্ধ থাকে তবে onPostExecuteআপনি এতে ব্যবহার করতে পারেন LocalBroadcastManager

LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent("finished"));

আপনার এও নিশ্চিত করতে হবে যে ক্রিয়াকলাপ বিরতি থাকা অবস্থায় সম্প্রচার পাঠানো হলে কার্যকলাপটি পরিস্থিতিটি সঠিকভাবে পরিচালনা করে।


1

এই পোস্টে একবার দেখুন । এই পোস্টটিতে AsyncTask দীর্ঘ চলমান ক্রিয়াকলাপ সম্পাদন করে এবং মেমরি ফাঁস হয় যখন একটি নমুনা প্রয়োগে স্ক্রিন ঘূর্ণন হয়। উত্স ফোর্জে নমুনা অ্যাপ্লিকেশনটি উপলব্ধ


0

আমার সমাধান।

আমার ক্ষেত্রে আমি একই প্রসঙ্গ সহ অ্যাসিঙ্কটাস্কের একটি শৃঙ্খল পেয়েছি। ক্রিয়াকলাপটির কেবলমাত্র প্রথমটিতে অ্যাক্সেস ছিল। চলমান কোনও কাজ বাতিল করার জন্য আমি নিম্নলিখিতগুলি করেছি:

public final class TaskLoader {

private static AsyncTask task;

     private TaskLoader() {
         throw new UnsupportedOperationException();
     }

     public static void setTask(AsyncTask task) {
         TaskLoader.task = task;
     }

    public static void cancel() {
         TaskLoader.task.cancel(true);
     }
}

কার্য doInBackground():

protected Void doInBackground(Params... params) {
    TaskLoader.setTask(this);
    ....
}

ক্রিয়াকলাপ onStop()বা onPause():

protected void onStop() {
    super.onStop();
    TaskLoader.cancel();
}

0
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    final AddTask task = mAddTask;
    if (task != null && task.getStatus() != UserTask.Status.FINISHED) {
        final String bookId = task.getBookId();
        task.cancel(true);

        if (bookId != null) {
            outState.putBoolean(STATE_ADD_IN_PROGRESS, true);
            outState.putString(STATE_ADD_BOOK, bookId);
        }

        mAddTask = null;
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    if (savedInstanceState.getBoolean(STATE_ADD_IN_PROGRESS)) {
        final String id = savedInstanceState.getString(STATE_ADD_BOOK);
        if (!BooksManager.bookExists(getContentResolver(), id)) {
            mAddTask = (AddTask) new AddTask().execute(id);
        }
    }
}

0

আপনি অ্যান্ড্রয়েডও যুক্ত করতে পারেন: configChanges = "কীবোর্ডহাইডেড | ওরিয়েন্টেশন | স্ক্রিনসাইজ"

আপনার প্রকাশিত উদাহরণে আমি আশা করি এটি সাহায্য করবে

 <application
    android:name=".AppController"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:theme="@style/AppTheme">
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.