web-dev-qa-db-fra.com

L'activité Android se recrée

Mon application fonctionne normalement très bien, jusqu'à ce que je rencontre un problème étrange sur un appareil spécifique. Il y a 2 activités dans App. Une fois que j'ai démarré ActivityB dans ActivityA, ActivityA commence sans problème. Cependant, après je retourne à l’ActivityA en appuyant sur le bouton matériel ou en appelant finish (); à l’intérieur de closeButton dans ActivityB, ActivityA se recharge elle-même. Il déclenche à nouveau onCreate () et recharge tout son contenu. Et je ne change pas l'orientation du téléphone. Ce comportement étrange apparaît uniquement dans 15 téléphones avec plus de 1 000 téléchargements de l'application. 

Ce problème ne se produit que sur Galaxy S3 Android OS 4.1.2. Et c'est aussi étrange.

Avez-vous une idée pourquoi cela se produit? 

Quand je commence une nouvelle activité à l'intérieur de l'écouteur de boutons comme ceci:

ActivityA.Java (MesajlarListViewActivity)

    public class MesajlarListViewActivity extends TrackedActivity {

    Context context = null;

    // contacts JSONArray
    JSONArray contacts = null;

    ArrayList<Message> productArray = new ArrayList<Message>();

    private ProductAdapter adapter;
    private ListView productList;
    private Runnable viewOrders;
    private HoloProgressIndicator profilInfoProgress = null;

    ImageView kapatButton = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mesajlar_list);

        context = this;

        kapatButton = (ImageView) findViewById(R.id.kapat_button);
        /* kapat button onclick listener. */
        // =================================================================================================================
        kapatButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view)
            {
                // Set vibration on touch.
                KnetGenericClass.vibratePhone(context);

                finish();
            }

        });
        // =================================================================================================================
        //Progress bar.
        profilInfoProgress = (HoloProgressIndicator) findViewById(R.id.profil_info_progress);

        // cheking internet connectivity.
        if(KnetGenericClass.checkInternetConnection(context))
        {
            // start task!
            /* internet var ise web service baglantisi kurmaya baslayabiliriz. */
            startActivityIndicatorWithThread();
        }
        else
        {
            KnetGenericClass.printErrorMessage(context, "Bağlantı Hatası",
                    "Lütfen internet bağlantınızı kontrol ediniz.");
        }

        productList = (ListView) findViewById(R.id.product_list);
        adapter = new ProductAdapter(this, R.layout.message_row, productArray);
        productList.setAdapter(adapter);

        // When user click a view on list view new page is appearing.
        productList.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {

                // Set vibration on touch.
                KnetGenericClass.vibratePhone(context);

                /* Navigate to message detay activity class with ilan ID. */
                Intent myIntent = new Intent(view.getContext(), MesajDetayActivity.class);
                myIntent.putExtra("messageID", productArray.get(position).getId());
                startActivity(myIntent);

                // setting image of clicked message null.
                RelativeLayout relativeLayout = (RelativeLayout) view;
                ImageView unreadedImageView = (ImageView) relativeLayout.findViewById(R.id.unreaded_image);
                unreadedImageView.setImageResource(0);
            }
        });
    }

    public class ProductAdapter extends ArrayAdapter<Message> {
        ArrayList<Message> items;

        public ProductAdapter(Context context, int textViewResourceId, ArrayList<Message> objects) {
            super(context, textViewResourceId, objects);
            this.items = objects;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            if(convertView == null)
            {
                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = vi.inflate(R.layout.message_row, null);
            }

            ImageView unreadedImageView = (ImageView) convertView.findViewById(R.id.unreaded_image);
            TextView productName = (TextView) convertView.findViewById(R.id.product_name);
            TextView productDetail = (TextView) convertView.findViewById(R.id.product_detail);
            // TextView productDate = (TextView)
            // convertView.findViewById(R.id.product_date);
            TextView sentDate = (TextView) convertView.findViewById(R.id.product_date);

            productName.setText(items.get(position).getSender());
            productDetail.setText(items.get(position).getTitle());
            // String bodyNoHTML = items.get(position).getBody();

            if(items.get(position).getIsReaded())
            {
                unreadedImageView.setImageResource(0);
            }
            else
            {
                unreadedImageView.setImageResource(R.drawable.bluedot);
            }

            String dateStr = items.get(position).getSentDate();
            try
            {
                sentDate.setText(dateStr.substring(6, 8) + "." + dateStr.substring(4, 6) + "." + dateStr.substring(0, 4)
                        +" "+dateStr.substring(8, 10)+":"+dateStr.substring(10, 12));
            }
            catch(Exception e)
            {
                sentDate.setText("");
            }


            return convertView;
        }

    }// @end of product adapter class.

    /* web service'e baglanti kurulan methodu threadin icerisinde cagiriyoruz. */
    public void startActivityIndicatorWithThread()
    {
        // ==============================================================================================
        // getting ilan details into arraylist.
        // setting up thread.
        viewOrders = new Runnable() {
            public void run()
            {
                getMessageListFromWebService();
            }
        };
        Thread thread = new Thread(null, viewOrders, "MagentoBackground");
        thread.start();
        profilInfoProgress.start();
        // ==============================================================================================
        // @end of the thread declaration.
    }

    public void getMessageListFromWebService()
    {
        // Creating JSON Parser instance
        JSONParser jParser = new JSONParser(context);

        // getting JSON string from URL
        JSONArray jsonArray = jParser.getAuthorizedInfoFromUrlToJSONArray(
                WebServiceInfo.getKnetWebServiceLink()+"/API/Member/GetInboxMessageList", MainActivity.getAccessToken());

        // if json is null then there is a problem.
        if(jsonArray == null)
        {
            // if json array is null then print error message.
            runOnUiThread(showAlertMessage);
            runOnUiThread(returnRes);
            return;
        }

        try
        {
            // Eger aranilan kritere gore ilan yok ise hata mesaji basiyoruz.
            if(jsonArray.length() == 0)
            {
                // if json array is null then print error message.
                runOnUiThread(showAlertIlanYokMessage);
                runOnUiThread(returnRes);
                return;
            }

            // looping through All Contacts
            for (int i = 0; i < jsonArray.length(); i++)
            {
                JSONObject c = jsonArray.getJSONObject(i);

                // Storing each json item in variable
                // String id = c.getString(TAG_ID);
                String id = c.getString("Id");
                String sender = c.getString("Sender");
                // String body = c.getString("Body");
                String title = c.getString("Title");
                String sentDate = c.getString("SentDate");
                Boolean isReaded = c.getBoolean("IsRead");

                Message productObject = new Message(id, sender, "", title, sentDate, isReaded);
                productArray.add(productObject);
            }
        }
        catch (Exception e)
        {
            Log.e("BACKGROUND_PROC", e.getMessage());
        }
        runOnUiThread(returnRes);
    }


    // @end of thread.
    private Runnable returnRes = new Runnable() {

        public void run()
        {
            profilInfoProgress.stop();
            adapter.notifyDataSetChanged();// refreshing data over adapter in
                                            // list view.
        }
    };

    // @end of thread.
    private Runnable showAlertMessage = new Runnable() {

        public void run()
        {
            // Bu hata genelde linkteki problemden, servera ulasilamamasindan
            // veya timeouttan meydana gelir.
            Toast.makeText(getApplicationContext(),
                    "Mesajlar alınamadı lütfen daha sonra tekrar deneyiniz.", 
                    Toast.LENGTH_LONG).show();
        }
    };

    private Runnable showAlertIlanYokMessage = new Runnable() {

        public void run()
        {
            // Bu hata aranilan kelimeye gore ilan bulunamazsa gelir.
            Toast.makeText(getApplicationContext(),
                    "Mesajlar bulunamadı.", 
                    Toast.LENGTH_LONG).show();
        }
    };

}

=============================================== =======================

ActivityB.Java (MesajDetayActivity.Java)

public class MesajDetayActivity extends TrackedActivity {

    private HoloProgressIndicator profilInfoProgress = null;

    TextView titleTextView = null;
    TextView senderTextView = null;
    TextView dateTextView = null;
    WebView bodyWebView = null;

    Message messageObject = null;

    String messageID = null;

    ImageView kapatButton = null;

    Context context;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mesajdetaylari);

        context = this;

        kapatButton = (ImageView) findViewById(R.id.kapat_button);
        /* kapat button onclick listener. */
        // =================================================================================================================
        kapatButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view)
            {
                // Set vibration on touch.
                KnetGenericClass.vibratePhone(context);

                finish();
            }

        });
        // =================================================================================================================
        //Progress bar.
        profilInfoProgress = (HoloProgressIndicator) findViewById(R.id.profil_info_progress);

        Bundle extras = getIntent().getExtras();
        if(extras != null)
        {
            messageID = extras.getString("messageID");
        }

        titleTextView = (TextView) findViewById(R.id.title_textview);
        senderTextView = (TextView) findViewById(R.id.sender_textview);
        dateTextView = (TextView) findViewById(R.id.date_textview);
        bodyWebView = (WebView) findViewById(R.id.mesaj_webView);

        // Show the ProgressDialog on this thread
        profilInfoProgress.start();

        // Start a new thread that will download all the data
        new MakeItTask().execute();

    }

    // Async task.
    private class MakeItTask extends AsyncTask<String, Void, Object> {
        protected Object doInBackground(String... args)
        {
            Log.i("MyApp", "Background thread starting");

            // This is where you would do all the work of downloading your data
            // getting message detay
            /* connect to web service */
            getMessageDetayFromWebService();

            return null;
        }

        protected void onPostExecute(Object result)
        {
            // Pass the result data back to the main activity
            // TakipListeActivity.this.data = result;
            try
            {
                titleTextView.setText("Başlık: " + messageObject.getTitle());
                senderTextView.setText("Gönderen: " + messageObject.getSender());
                dateTextView.setText("Tarih: " + messageObject.getSentDate().substring(6, 8) + "."
                        + messageObject.getSentDate().substring(4, 6) + "."
                        + messageObject.getSentDate().substring(0, 4));

                if(!messageObject.getBody().contains("img"))
                {
                    bodyWebView.loadDataWithBaseURL(null, messageObject.getBody(), "text/html", "UTF-8", null);
                }

            }
            catch (Exception e)
            {
                Log.e(CONNECTIVITY_SERVICE, "Mesaj Detayi bilgileri basilamadi.");
            }

            profilInfoProgress.stop();
        }
    }

    /* web service'e baglanti kurulan methodu threadin icerisinde cagiriyoruz. */
    public void getMessageDetayFromWebService()
    {
        // Creating JSON Parser instance
        JSONParser jParser = new JSONParser(context);

        // getting JSON string from URL
        JSONObject jsonObject = jParser.getAuthorizedInfoFromUrlToJSONObject(
                WebServiceInfo.getKnetWebServiceLink()+"/API/Member/GetInboxMessage/" + messageID, MainActivity.getAccessToken());

        // if json is null then there is a problem.
        if(jsonObject == null)
        {
            return;
        }

        try
        {
            String title = jsonObject.getString("Title");
            String id = jsonObject.getString("Id");
            String sender = jsonObject.getString("Sender");
            String date = jsonObject.getString("SentDate");
            String body = jsonObject.getString("Body");

            messageObject = new Message(id, sender, body, title, date, true);

        }
        catch (Exception e)
        {
            Log.e("BACKGROUND_PROC", e.getMessage());
        }

    }// @end of getIlanDetayFromWebService.

}

Edit: Non seulement ces deux activités ont ce problème, toutes les activités agissant même comportement sur certains téléphones.

17
OzBoz

Vérifiez si Ne pas conserver les activités sous Paramètres > Système > Options du développeur > Applications est activé ou non.

42
Joe

La documentation de l'activité ( http://developer.Android.com/reference/Android/app/Activity.html ) indique ce qui suit sur le cycle de vie d'une activité en arrière-plan:

Une activité en arrière-plan (activité non visible par l'utilisateur et suspendue) n'est plus critique. Le système peut donc arrêter en toute sécurité son processus pour récupérer de la mémoire pour d'autres processus en avant-plan ou visibles. Si son processus doit être interrompu, lorsque l'utilisateur revient à l'activité (en la rendant visible à nouveau à l'écran), sa méthode onCreate (Bundle) est appelée avec le savedInstanceState qu'il avait précédemment fourni dans onSaveInstanceState (Bundle) afin qu'il peut se redémarrer dans le même état que celui où l'utilisateur l'a laissé.

En d'autres termes, ActivityA peut ou ne peut pas être détruit par le système d'exploitation tant que ActivityB est actif. Cette situation doit donc être gérée dans le code. Si ActivityA a été détruit, onCreate (Bundle) sera appelé lorsque l'utilisateur appuiera sur le bouton Précédent dans ActivityB.

9
Mads Frandsen

Il existe un paramètre de développeur Android appelé "Ne pas garder les activités". La description de cette option est "Détruit chaque activité dès que l'utilisateur la quitte". Cela ressemble à une bonne description de ce que vous voyez, et comme vous ne le voyez que sur quelques téléphones, l’idée que cela est causé par un paramètre système autre que celui par défaut semble plausible.

Idéalement, votre application fonctionnerait toujours dans ce scénario, même si elle était moins optimale. Mais si ce paramètre pose un problème pour votre application, vous souhaiterez peut-être le documenter pour vos utilisateurs.

8
j__m

Avez-vous essayé de changer la launchmode dans le manifeste Android? Essayez d'ajouter ceci à votre déclaration d'activité:

Android:launchMode="singleTask"

Ensuite, essayez d'utiliser startActivityForResult au lieu de startActivity. Cela forcera l'activité A à appeler sa méthode onActivityResult(int, int, Intent) à la fin de l'activité B - ce qui peut ignorer cet appel (bogué) à onCreate. Ensuite, dans l'activité A, implémentez la méthode pour effectuer quelque chose (comme imprimer une instruction de débogage):

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    Log.i("Test", "Did this work???");
    //TODO send notification to your server to verify this works?
}
7
Phil

Je ne vois aucun problème dans ce comportement.

Si vous souhaitez conserver l’état de ActivityA, utilisez les méthodes onSaveInstanceState et onRestoreInstanceState. Voir Cycle de vie de l'activité à http://developer.Android.com/reference/Android/app/Activity.html#ActivityLifecycle pour plus de détails.

Voir aussi https://stackoverflow.com/a/10492967/332210 pour une compréhension plus approfondie.

5
Gaurav Vaish

Vous pouvez essayer une chose de fournir votre mise en page dans onCreate() et faire le reste du travail dans onStart() ?? si ça marche??

COMME:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.show);
   }

et 

      @Override
       protected void onStart() {
       // TODO Auto-generated method stub
    super.onStart();
    Log.i(TAG, "On Start .....");

      }

Voir Cycle de vie de l'activitéenter image description here

2
Shiv

Remplacez les méthodes onStart () et onResume dans l'activité A et vérifiez si le problème persiste. et si possible, donnez votre code d'activité A et B ici.

1
Dinesh Prajapati

Peut-être devriez-vous utiliser

Intent startIntent = new Intent(view.getContext(), ActivityB.class); 
startActivity(startIntent); 
finish() ;

Et

Intent startIntent = new Intent(view.getContext(), ActivityA.class); 
startActivity(startIntent); 
finish() ;

chaque fois que vous revenez en arrière ou en avant.

1
Husnain Iqbal

Je pense que ce n'est pas à cause de la mémoire la limite. 

https://www.box.com/s/7pd0as03bb8wwumuc9l9

Vous devez tester ces deux activités et vérifier si cela se produit également ou non dans cet exemple. Veuillez également partager le contenu de votre fichier AndroidManifest.xml, cela facilitera le débogage.

1
umesh

Il a également fait face au problème exact et résolu le problème en utilisant Android:launchMode="standard" dans activity sur manifest

1
Avadhani Y

L'activité A utilise la mise en page R.layout.mesajlar_list

L'activité B utilise la mise en page R.layout.mesajdetaylari

Mais les deux ont la ligne de code suivante:

kapatButton = (ImageView) findViewById(R.id.kapat_button);

Dans quelle disposition R.id.kapat_button se trouve-t-il? Utiliser le même identifiant dans différentes configurations est une opération très risquée. Je ne peux pas garantir que cela cause ce que vous voyez, mais c'est le genre de chose qui peut provoquer un comportement étrange.

1
Neil Townsend

J'ai eu ce problème récemment, et cela me rend agacé. Je pense que cette question autour de 2 options solution à vérifier, mais inutile. 

À propos du paramètre "Ne pas garder les activités" corrigé ici, j'ai utilisé ce code pour vérifier qu'il était facultatif ou non coché (mon périphérique de test personnalise la base sur la version 2.3.5 et n'affiche pas cette option):

private boolean isAlwaysFinishActivitiesOptionEnabled() {
    int alwaysFinishActivitiesInt = 0;
    if (Build.VERSION.SDK_INT >= 17) {
        alwaysFinishActivitiesInt = Settings.System.getInt(getApplicationContext().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0);
    } else {
        alwaysFinishActivitiesInt = Settings.System.getInt(getApplicationContext().getContentResolver(), Settings.System.ALWAYS_FINISH_ACTIVITIES, 0);
    }

    if (alwaysFinishActivitiesInt == 1) {
        return true;
    } else {
        return false;
    }
}

La vérification du résultat est fausse dans mon cas. Je vérifie également la mémoire lors de l'exécution de l'application et rien ne se produit.

0
Fuong Lee

vous pouvez utiliser Android:launchMode="singleTop"in manifeste.

<activity
        Android:name=".MainActivity"
        Android:label="@string/app_name"
        Android:launchMode="singleTop"
        Android:configChanges="orientation|keyboardHidden|screenSize"
        Android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN"/>

            <category Android:name="Android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
0
Abu Nayem