Активность Android воссоздает себя

Мое приложение работает нормально, пока я не столкнулся с какой-то странной проблемой на конкретном устройстве. В приложении есть 2 мероприятия. После того, как я запустил ActivityB внутри ActivityA, ActivityA начнет без проблем. Однако после того, как я вернусь к ActivityA с нажатием кнопки аппаратного обеспечения или вызовом finish(); внутри closeButton в ActivityB, ActivityA перезагружается. Он снова запускает onCreate() и перезагружает все его содержимое. И я не меняю ориентацию телефона. Это странное поведение появляется только в 15 телефонах за 1.000 загрузки приложения.

Эта проблема возникает только в ОС Android Galaxy S3 4.1.2. И это тоже странно.

У вас есть идея, почему это происходит?

Когда я запускаю новую активность внутри пульта, например:

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.

}

Изменить: не только эти два действия имеют эту проблему, но и все действия, действующие на некоторых телефонах.

Ответы

Ответ 1

Убедитесь, что Не выполнять действия Настройки > Система > Параметры разработчика > > Приложения.

Ответ 2

Документация по действиям (http://developer.android.com/reference/android/app/Activity.html) рассказывает о жизненном цикле фоновой активности:

Фоновая активность (активность, которая не видна пользователю и приостановлена) больше не критична, поэтому система может безопасно убить свой процесс для восстановления памяти для других передних или видимых процессов. Если его процесс должен быть убит, когда пользователь перейдет к действию (сделав его видимым на экране снова), его метод onCreate (Bundle) будет вызван с сохраненнымInstanceState, который он ранее поставил в onSaveInstanceState (Bundle), чтобы он может перезапустить себя в том же состоянии, в котором пользователь оставил его.

Другими словами, ActivityA может или не может быть уничтожен операционной системой, в то время как ActivityB активен, поэтому эту ситуацию нужно обрабатывать в коде. Если ActivityA будет уничтожен, будет вызываться onCreate (Bundle), когда пользователь нажимает кнопку "Назад" в ActivityB.

Ответ 3

Вы пытались изменить launchmode в манифесте Android? Попытайтесь добавить это в свою декларацию активности:

android:launchMode="singleTask"

Затем попробуйте использовать startActivityForResult вместо startActivity. Это заставит Activity A вызвать свой метод onActivityResult(int, int, Intent), когда закончится Activity B, - который может пропустить этот (багги) вызов onCreate. Затем в Activity A реализуем метод для выполнения чего-либо (например, для печати инструкции отладки):

@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?
}

Ответ 4

Там есть установка Android-разработчика под названием "Не выполнять действия". Описание этого параметра: "Уничтожьте каждое действие, как только пользователь его покинет". Это похоже на хорошее описание того, что вы видите, и поскольку вы видите его только на нескольких телефонах, идея о том, что это вызвано нестандартной настройкой системы, кажется правдоподобной.

В идеале ваше приложение будет работать в этом сценарии, даже если оно будет менее оптимальным. Но если этот параметр является проблемой для вашего приложения, вы можете документировать эту проблему для своих пользователей.

Ответ 5

Я не вижу никаких проблем в этом поведении.

Если вы хотите сохранить состояние ActivityA, используйте методы onSaveInstanceState и onRestoreInstanceState. Дополнительную информацию см. В разделе "Жизненный цикл деятельности" http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle.

См. также fooobar.com/questions/350398/... для более глубокого понимания.

Ответ 6

Вы можете попробовать одну вещь, обеспечивающую ваш макет в onCreate(), и выполните оставшуюся часть работы в onStart()? если он работает?

LIKE:

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

и

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

      }

См. Жизненный цикл активности enter image description here

Ответ 7

Возможно, вы должны использовать

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

и

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

каждый раз, когда вы возвращаетесь или вперед.

Ответ 8

Он тоже столкнулся с точной проблемой и решил проблему, используя android:launchMode="standard" в activity of manifest.

Ответ 9

Переопределите onStart() и метод onResume в Activity A и проверьте, сохраняется ли проблема. и, если возможно, предоставьте здесь свой код активации A и B.

Ответ 10

Действие A использует макет R.layout.mesajlar_list

Активность B использует макет R.layout.mesajdetaylari

Но обе имеют следующую строку кода:

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

В каком макете находится файл R.id.kapat_button? Использование одного и того же идентификатора в разных макетах - очень рискованная вещь. Я не могу гарантировать, что это приведет к тому, что вы видите, но это то, что может вызвать странное поведение.

Ответ 11

Я думаю, что это не из-за ограничения памяти.

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

Вы должны проверить эти два действия и проверить, происходит ли это в этом примере или нет. Поделитесь своим содержимым файлов AndroidManifest.xml, это поможет с отладкой.

Ответ 12

Недавно я получил эту проблему, и это меня раздражало. Я думаю, что проблема вокруг 2 вариантов решения проверить, но бесполезно.

О настройке "Не продолжать действия" исправлено здесь, я использовал этот код, чтобы проверить, что он опционально проверен или нет (мое тестовое устройство настраивает базу на версии 2.3.5 и не показывает эту опцию):

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

Проверка результата в моем случае неверна. Я также проверяю память при запуске приложения, и ничего не происходит.

Ответ 13

вы можете использовать android:launchMode="singleTop" в манифесте.

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