2014-02-14 4 views
0

Я видел много похожих вопросов о stackoverflow, но не могу понять, что я делаю неправильно. Я сделал очень простое приложение для репликации ошибки.Android: IllegalStateException: активность была разрушена

Приложение выполняет следующие действия:
добавляет фрагмент в mainActivty's onCreate.
Пользователь может добавить еще один фрагмент из диалогового окна.
, когда диалог вызывает метод addFragment MainActivity, исключение генерируется при совершении транзакции.

Вот MainActivity

package com.example.testapp; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentTransaction; 
import android.view.View; 
import android.widget.Button; 

public class MainActivity extends FragmentActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    final Button button = (Button) findViewById(R.id.add_button); 
    button.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      AddButtonDialog addButtonDialog = new AddButtonDialog(); 
      addButtonDialog.show(getSupportFragmentManager(), "ADD"); 
     } 
    }); 

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
    CustomFragment fragment = new CustomFragment(); 
    transaction.add(R.id.fragment_container, fragment); 
    transaction.commit(); 
} 


public void addButton() { 
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
    CustomFragment fragment = new CustomFragment(); 
    transaction.add(R.id.fragment_container, fragment); 
    transaction.commit(); // <-- Exception 

} 

} 

и вот AddButtonDialog, что называет MainActivity

public class AddButtonDialog extends DialogFragment { 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
     final LayoutInflater inflater = getActivity().getLayoutInflater(); 
     View view = inflater.inflate(R.layout.new_button_dialog, null); 
     builder.setView(view) 

       .setPositiveButton("Add", new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int id) { 
         MainActivity main = new MainActivity(); 
         main.addButton(); 
        } 
       }); 
     return builder.create(); 
    } 
} 

А вот StackTrace

02-14 10:09:27.781: E/AndroidRuntime(26291): FATAL EXCEPTION: main 
    02-14 10:09:27.781: E/AndroidRuntime(26291): java.lang.IllegalStateException: Activity has been destroyed 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1365) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at com.example.testapp.MainActivity.addButton(MainActivity.java:35) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at com.example.testapp.AddButtonDialog$1.onClick(AddButtonDialog.java:22) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:185) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at android.os.Handler.dispatchMessage(Handler.java:99) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at android.os.Looper.loop(Looper.java:137) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at android.app.ActivityThread.main(ActivityThread.java:5328) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at java.lang.reflect.Method.invokeNative(Native Method) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at java.lang.reflect.Method.invoke(Method.java:511) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
    02-14 10:09:27.781: E/AndroidRuntime(26291): at dalvik.system.NativeStart.main(Native Method) 

Я довольно уверен, что я не являюсь понимая концепции жизненного цикла фрагмента. Пожалуйста, кто-нибудь будет так добр, чтобы объяснить, что я делаю неправильно.

+2

'MainActivity main = new MainActivity();' dont do this. Вы не должны пытаться создавать операции –

+0

Спасибо.Каков правильный способ вызова метода в моей основной деятельности? – Fuzz

+0

Попробуйте 'MainActivity.this.add()' –

ответ

1

Передайте ссылку на MainActivity в диалог и попробовать это

mainActivity.addButton() 

Где mainActivity является эталонным

0

не:

MainActivity main = new MainActivity(); 
        main.addButton(); 

путь, чтобы начать деятельность в Android осуществляется через startActivity (умысел); Метод

Так, например, вместо того, чтобы сделать:

Intent intent = new Intent(this, MainActivity.class); 
startActivity(intent); 

см Intent Guide

+0

Спасибо за ваш быстрый ответ. Итак, как бы я назвал метод в своей основной деятельности правильным способом? – Fuzz

+0

ах ... вы просто хотите вызвать метод. Я думал, что вы участвуете в другом мероприятии, и вы хотите запустить MainActiviy из своего диалога. – donfuxx

+0

Нет, я предполагаю, что Activity уже запущена с его просто диалогового окна поверх него. Вы знаете, как я это выполнил? – Fuzz

0

Если AddButtonDialog является внутренний класс, то просто сделать вызов AddActivity, а не делать main.addButton().

Если нет, попробуйте создать этот метод в отдельном классе и передать FragmentManager в качестве параметра к нему. Таким образом, вы можете вызвать это из любого места, создавая экземпляр нового класса.

Кроме того, попробуйте использовать ниже в методе AddButton,

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
CustomFragment fragment = new CustomFragment(); 
transaction.replace(R.id.fragment_container, fragment); //this will replace your fragment_container with this fragment 
transaction.addToBackStack(null);// this will help you get back to your first fragment on back press 
transaction.commit(); 
+0

Благодарим за отзыв. Простите мое невежество, но как я могу назвать addActivity? Я просто хотел бы вызвать метод в моем основном классе, который добавляет новый фрагмент (From My Dialog). – Fuzz

+0

- ваш класс Dialog - внутренний класс, он написан в MainActivity? –

0

Если все, что вы хотите сделать, это вызов метода в вашей деятельности из другого места:
1 - создать статическую переменную в вашем основном действии, тип Activity и создать экземпляр в onCreate, чтобы этот экземпляр хранился.
2 - создать статический метод в вашей основной деятельности под названием получить экземпляр, который просто возвращает экземпляр вашей деятельности
3 - где бы вы ни вызов: MainActivity.getInstance().yourMethod();
Конечно, это будет работать только, если ваша деятельность существующая!

Смежные вопросы