मेरे पास कई गतिविधियों के साथ एक ऐप है, और उनमें से बहुत से डेटा लोड करने और दिखाने के लिए विभिन्न जेसन वेब एपीआई हिट करते हैं। एक सामान्य पैटर्न के समान है:

public class MyActivity extends Activity {
    public void OnCreate(Bundle savedInstanceState) {
        ...
        ProgressDialog pd = ProgressDialog.show( ... );

        // This is a custom API which wraps AsynkTask and calls my callback in onPostExecute
        DoWebThing(url, new Callback() {
            public void onSuccess(String json) {
                pd.dismiss();
                // Do other UI stuff with the json data
            }
        });
    }
}

यह बहुत अच्छा काम करता है, और बहुत सारे कोड स्निपेट के समान है जो आपको SO और ट्यूटोरियल पर मिलेगा। समस्या यह है कि पृष्ठभूमि प्रक्रिया चल रही है, जबकि उपयोगकर्ता पृष्ठ छोड़ सकता है। इस मामले में, मुझे दृश्य (प्रोग्रेसडिअलॉग) को लीक करने के बारे में लॉगकैट त्रुटि मिलती है, और फिर जब मैं इसे खारिज कर देता हूं या अपनी अन्य यूआई सामग्री करता हूं तो मैं क्रैश हो जाऊंगा।

मैंने सफलता पर प्रारंभिक जांच जोड़ने का प्रयास किया है:

if (!pd.isShowing()) {
    return;
}

यह कुछ उपकरणों पर क्रैश को ठीक करता है, लेकिन अन्य को नहीं, और हमें अभी भी लीक हुए दृश्य के बारे में लॉगकैट त्रुटि मिलती है।

मैंने pd.isShowing() चेक को MyActivity.this.isFinishing() से बदलने की कोशिश की है, जो कुछ भी मदद नहीं करता है (जिस डिवाइस पर मैं वर्तमान में परीक्षण कर रहा हूं)। अभी भी लॉगकैट त्रुटि और क्रैश प्राप्त करें।

मैंने MyActivity.this.isDestroyed() की कोशिश की है, जो दुर्घटना को ठीक करता है, लेकिन केवल एसडीके 17+ पर काम करता है और फिर भी लॉगकैट त्रुटि प्राप्त करता है।

इसे सही मायने में ठीक करने का एकमात्र विकल्प मेरे प्रगति संवाद को एक सदस्य चर बनाना और OnDestroy() को ओवरराइड करना है:

ProgressDialog mPd;
@Override
protected void onDestroy() {
    super.onDestroy();
    if (mProgressDialog != null) {
        mProgressDialog.dismiss();
        mProgressDialog = null;
    }
}

अब मेरे कॉलबैक में मैं जांच सकता हूं कि mProgressDialog == null.

यह बहुत अच्छा काम करता है। एक दृश्य लीक करने के बारे में कोई दुर्घटना और कोई लॉगकैट त्रुटि नहीं। लेकिन यह बहुत सारे बॉयलरप्लेट की तरह लगता है - मुझे प्रगति संवाद को एक सदस्य चर बनाना है और OnDestroy() को मेरी सभी (कई) गतिविधियों में ओवरराइड करना है जो पृष्ठभूमि सामग्री करते हैं।

मुझे एक बेहतर विकल्प नहीं दिख रहा है, लेकिन मैं बहुत सारी गतिविधियों को अपडेट करना शुरू करने से पहले दूसरी राय चाहता था।

2
Brad 21 सितंबर 2018, 05:48

1 उत्तर

सबसे बढ़िया उत्तर

NetworkBaseActivity कहें, एक गतिविधि बनाएं। इस गतिविधि में प्रोग्रेसडिअलॉग बनाएं और ऑनडेस्ट्रॉय को संभालें। डायलॉग (उपवर्गों से) दिखाने और छिपाने के लिए showMyDialog() और hideMyDialog() नामक एक विधि भी बनाएं। अब आपकी सभी गतिविधियाँ जो पृष्ठभूमि सामग्री करती हैं, केवल इस गतिविधि को विस्तारित करने की आवश्यकता है। डायलॉग कॉल दिखाने के लिए showMyDialog() और इसे छिपाने के लिए hideMyDialog() पर कॉल करें

कुछ इस तरह:

public class NetworkBaseActivity extends AppCompatActivity{
    ProgressDialog myDialog;
    onCreate(Bundle bundle){
        // initialize myDialog
    }

    public void showDialog(){
       // show myDialog if not shown
    }
    public void hideDialog(){
      // hide myDialog if already shown
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mProgressDialog != null) {
        mProgressDialog.dismiss();
        mProgressDialog = null;
    }
}

public class YourActivity extends NetworkBaseActivity{

}

मैंने कोड को स्टैक ओवरफ्लो में सही टाइप किया है, इसलिए मेरे टाइपो को क्षमा करें, लेकिन आपको यह विचार मिलता है।

1
nupadhyaya 21 सितंबर 2018, 06:31