android - स्क्रीन रोटेशन के दौरान AsyncTask को कैसे संभालें?




android-asynctask screen-rotation (9)

मैंने अपनी आवृत्ति स्थिति को कैसे सहेजना है या स्क्रीन रोटेशन के दौरान मेरी गतिविधि को नष्ट करने के तरीके से निपटने के तरीके पर बहुत कुछ पढ़ा है।

ऐसी कई संभावनाएं प्रतीत होती हैं लेकिन मुझे पता नहीं चला है कि कौन सा असिनकटास्क के परिणाम पुनर्प्राप्त करने के लिए सबसे अच्छा काम करता है।

मेरे पास कुछ AsyncTasks हैं जिन्हें बस फिर से शुरू किया गया है और गतिविधि की isFinishing() विधि को कॉल करें और यदि गतिविधि समाप्त हो रही है तो वे कुछ भी अपडेट नहीं करेंगे।

समस्या यह है कि मेरे पास एक कार्य है जो किसी वेब सेवा का अनुरोध करता है जो कार्य को विफल या सफल और पुनरारंभ करने के लिए उपयोगकर्ता के लिए वित्तीय हानि का परिणाम देगा।

आप इसे कैसे हल करेंगे? संभावित समाधान के फायदे या नुकसान क्या हैं?


आप code.google.com/p/shelves पर AsyncTask s और अभिविन्यास परिवर्तनों को कैसे प्रबंधित कर सकते हैं, यह देख सकते हैं। ऐसा करने के कई तरीके हैं, जिसे मैंने इस ऐप में चुना है, वह वर्तमान में चल रहे किसी भी कार्य को रद्द करना है, अपनी स्थिति को सहेजना है और नई Activity सहेजे गए राज्य के साथ एक नया प्रारंभ करना है। ऐसा करना आसान है, यह अच्छी तरह से काम करता है और बोनस के रूप में जब उपयोगकर्ता ऐप छोड़ देता है तो यह आपके कार्यों को रोकने का ख्याल रखता है।

आप अपनी AsyncTask को नई Activity पास करने के लिए onRetainNonConfigurationInstance() पर भी उपयोग कर सकते हैं onRetainNonConfigurationInstance() पिछली Activity इस तरह से लीक करने के बारे में सावधान रहें।)


आप एंड्रॉइड भी जोड़ सकते हैं: 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">

इसका सबसे उचित तरीका रोटेशन पर एसिंक कार्य के उदाहरण को बनाए रखने के लिए एक टुकड़े का उपयोग करना है।

यहां बहुत सरल उदाहरण का एक लिंक दिया गया है जिससे इस तकनीक को आपके ऐप्स में एकीकृत करना आसान हो जाता है।

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


एंड्रॉइड द्वारा प्रदान किए गए सिंगलटन पर आप हमेशा मौजूदा AsyncTask का संदर्भ क्यों नहीं रखते?

जब भी कोई कार्य शुरू होता है, प्रीएक्सक्यूट या निर्माता पर, आप परिभाषित करते हैं:

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

जब भी यह खत्म हो जाता है तो आप इसे शून्य पर सेट करते हैं।

इस तरह आपके पास हमेशा एक संदर्भ होता है जो आपको कुछ विशिष्ट करने की अनुमति देता है, ऑनरेट या ऑन्यूज आपके विशिष्ट तर्क के लिए विनियमित है:

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

यदि यह शून्य है तो आप जानते हैं कि वर्तमान में कोई भी नहीं चल रहा है!

:-)


मेरा पहला सुझाव यह सुनिश्चित करना होगा कि आपको वास्तव में स्क्रीन रोटेशन (डिफ़ॉल्ट व्यवहार) पर रीसेट करने के लिए अपनी गतिविधि की आवश्यकता हो। हर बार जब मुझे रोटेशन के साथ समस्याएं होती हैं तो मैंने एंड्रॉइडमैनीफेस्ट.एक्सएमएल में अपने <activity> टैग में यह विशेषता जोड़ दी है, और ठीक है।

android:configChanges="keyboardHidden|orientation"

यह अजीब लग रहा है, लेकिन यह आपके onConfigurationChanged() विधि को क्या करता है, अगर आप इसे आपूर्ति नहीं करते हैं तो यह लेआउट को फिर से मापने के अलावा कुछ भी नहीं करता है, जो सबसे अधिक घुमाव को संभालने का एक बिल्कुल सही तरीका प्रतीत होता है समय की।


मेरा समाधान

मेरे मामले में मुझे उसी संदर्भ के साथ AsyncTasks की एक श्रृंखला मिली है। गतिविधि केवल पहले तक पहुंच थी। किसी भी चल रहे कार्य को रद्द करने के लिए मैंने निम्नलिखित किया:

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() या onStop() onPause() :

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

यह एंड्रॉइड के बारे में मैंने देखा सबसे दिलचस्प सवाल है !!! असल में मैं पिछले महीनों के दौरान पहले से ही समाधान की तलाश कर रहा हूं। अभी भी हल नहीं किया है।

सावधान रहें, बस ओवरराइड करें

android:configChanges="keyboardHidden|orientation"

सामान पर्याप्त नहीं है।

जब आपके AsyncTask चल रहा है, तो उपयोगकर्ता को फ़ोन कॉल प्राप्त होने पर उस मामले पर विचार करें। आपका अनुरोध पहले ही सर्वर द्वारा संसाधित किया जा रहा है, इसलिए AsyncTask प्रतिक्रिया के लिए प्रतीक्षारत है। इस पल में आपका ऐप पृष्ठभूमि में चला जाता है, क्योंकि फोन ऐप सिर्फ अग्रभूमि में आया है। पृष्ठभूमि में होने के बाद से ओएस आपकी गतिविधि को मार सकता है।


विचार करने की एक बात यह है कि AsyncTask का नतीजा केवल उस गतिविधि के लिए उपलब्ध होना चाहिए जिसने कार्य शुरू किया था। यदि हां, तो रोमैन गाय का जवाब सबसे अच्छा है। यदि यह आपके आवेदन की अन्य गतिविधियों के लिए उपलब्ध होना चाहिए, तो onPostExecute आप onPostExecute का उपयोग कर सकते हैं।

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

आपको यह सुनिश्चित करने की भी आवश्यकता होगी कि जब गतिविधि रोक दी जाती है तो प्रसारण को भेजे जाने पर गतिविधि सही तरीके से संभालती है।


@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);
        }
    }
}




screen-rotation