दिलचस्प पोस्ट
जावा में सर्वश्रेष्ठ संगामिति सूची चुनना INTENT इंटरनेट कनेक्शन की जांच करें संख्या को स्ट्रिंग में कैसे परिवर्तित करें और इसके विपरीत सी ++ में रूपांतरण कैसे करें Android एप्लिकेशन आईडी कैसे प्राप्त करें? जावास्क्रिप्ट में बंद – क्या गलत है? सैमसंग गैलेक्सी एस II एवीडी (एंड्रॉइड वर्चुअल डिवाइस) बेसिक सेटिंग्स? libxml / tree.h ऐसी कोई फ़ाइल या निर्देशिका नहीं है स्ट्रिंग पर स्विम का एक ट्रिम विधि है? सी में एक स्ट्रिंग पर स्विच करने का सबसे अच्छा तरीका ओपनसीवी 2.3 सी – छवि के अंदर ऑब्जेक्ट अलग कैसे करें कैसे चेक करें कि ऑब्जेक्ट (वेरिएबल) को आर में परिभाषित किया गया है? Play में वर्तमान लूप का सूचक प्राप्त कर रहा है! 2 स्कला टेम्पलेट Http://java.sun.com/jsf/facelets के लिए टैग लाइब्रेरी डिस्क्रिप्टर नहीं मिल सकता है एक चरित्र निरंतर में एकाधिक वर्ण हर प्रोग्राम में लिखने के लिए एंड्रॉइड डेवलपमेंट के लिए अपनी खुद की लाइब्रेरी कैसे तैयार की जाए?

स्क्रीन रोटेशन के दौरान एक एसिंक टास्क कैसे प्रबंधित करें?

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

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

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

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

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

Solutions Collecting From Web of "स्क्रीन रोटेशन के दौरान एक एसिंक टास्क कैसे प्रबंधित करें?"

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

 android:configChanges="keyboardHidden|orientation" 

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

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

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

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

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

 android:configChanges="keyboardHidden|orientation" 

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

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

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

जब भी कोई कार्य प्रारंभ हो, PreExecute या बिल्डर पर, आप परिभाषित करते हैं:

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

जब भी यह खत्म हो जाएगा आप इसे रिक्त करने के लिए सेट करें

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

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

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

🙂

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

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

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

Pro android 4 लेखक ने एक अच्छा तरीका सुझाया है, कि आपको weak reference उपयोग करना चाहिए।

कमजोर संदर्भ नोट

मेरे दृष्टिकोण को देखने के लिए, asynctask को onRetainNonConfigurationInstance द्वारा वर्तमान गतिविधि ऑब्जेक्ट से decoupling और उन्मुखीकरण परिवर्तन के बाद इसे एक नई गतिविधि ऑब्जेक्ट के साथ बाध्य करने के लिए बेहतर है। यहां मुझे एक बहुत अच्छा उदाहरण मिला है कि कैसे AsyncTask और ProgressDialog के साथ काम करना है I

एंड्रॉइड: पृष्ठभूमि संसाधन / कॉन्फ़िगरेशन परिवर्तन के साथ Async Opeartion

पृष्ठभूमि प्रक्रिया के दौरान async opeartion के राज्यों को बनाए रखने के लिए: आप टुकड़ों की मदद ले सकते हैं।

निम्नलिखित कदम देखें:

चरण 1: हेडरलेस टुकड़ा बनाएं पृष्ठभूमि कार्य को कहें और इसके साथ एक निजी एसिंक कार्य वर्ग जोड़ें।

चरण 2 (वैकल्पिक चरण): यदि आप कोड के नीचे अपनी गतिविधि उपयोग के शीर्ष पर लोडिंग कर्सर रखना चाहते हैं:

चरण 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 } 

}

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

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

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

इस पोस्ट को देखें इस पोस्ट में एक सैम्पल एप्लीकेशन में स्क्रीन रोटेशन होने पर एसिंक टास्क लंबे समय से चलने वाले ऑपरेशन और मेमरी रिसाव को शामिल करता है। नमूना एप्लिकेशन स्रोत फोर्ज पर उपलब्ध है

मेरा समाधान

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

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

आप एंड्रॉइड भी जोड़ सकते हैं: configChanges = "keyboardHidden | अभिविन्यास | स्क्रीन आकार"

आपके स्पष्ट उदाहरण के लिए मुझे उम्मीद है कि यह मदद करेगा

  <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">