Android: как отправить интерфейс из одной активности в другую

У меня есть такой интерфейс:

public interface MyInterface {
    public void aMethod();
}

Мой пользовательский объект:

public class MyObject {

    private Context context;
    private MyInterface inter;

    public MyObject(Context context) {
        this.context = context;
        this.inter = (MyInterface) this.context;
        inter.aMethod();
    }
}

Основная деятельность:

public class MainActivity extends Activity implements MyInterface {

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

        MyObject my = new MyObject(this);

    }

    @Override
    public void aMethod() {
        Toast.makeText(this, "done", Toast.LENGTH_SHORT).show();
    }
}  

Здесь внутри конструктора MyObject я могу получить интерфейс из контекста, а затем связаться с Activity.

Но как я могу отправить интерфейс из одной активности в другую?
Мне нужно вызвать метод внутри Activity1 из Activity2
Есть ли способ?

Примечание: я не хочу использовать фрагмент.

Ответы

Ответ 1

Прежде всего, это очень плохо:

this.inter = (MyInterface) this.context;

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

public class MyObject {

    private Context context;
    private MyInterface inter;

    public MyObject(Context context, MyInterface inter) {
        this.context = context;
        this.inter =  inter;
        inter.aMethod();
    }
}

Таким образом, это намного безопаснее и чище.


Чтобы отправить Object другому Activity убедитесь, что он реализует Serializable следующим образом:

public interface MyInterface extends Serializable {
    public void aMethod();
}

И теперь вы можете просто добавить интерфейс, как дополнительный к Intent, который запускает другую Activity:

Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("interface", inter);
startActivity(intent);

И в OtherActivity вы можете получить Object от Intent следующим образом:

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

    Intent intent = getIntent();
    MyInterface inter = (MyInterface) intent.getSerializableExtra("interface");

    ...
}

РЕДАКТИРОВАТЬ:

Когда вы делаете что-то подобное в своей Activity вы создаете анонимный класс:

OnCreateListener inter = new OnCreateListener() {

    @Override
    public void onObjCreate() {
        Log.d("pltk", "dfgbfdgh");
    }
};

Дело в таком анонимном классе заключается в том, что они не являются статическими, то есть вы все равно можете получать доступ к методам и переменным из класса, в котором этот слушатель вложен. Внутренне причина этого заключается в том, что этот новый класс сохраняет ссылку на экземпляр класса, который его создал, в вашем случае ограждающих Activity. Это великая вещь, и мы используем все это время для OnClickListener и т.д. Но в вашем случае это проблема, потому что вы хотите отправить этот Object в другую Activity. Внутренняя ссылка на старую Activity позволяет сериализовать ее, и это хорошо. Если бы вы могли просто отправить Object вроде этого, вы бы создали утечки памяти, как сумасшедшие, из-за всех старых ссылок, которые сборщик мусора не может собрать.

Решение довольно просто, вы можете либо определить класс в своем собственном файле, либо сделать класс статическим. Статический в этом контексте означает, что класс по существу трактуется так же, как и в его собственном отдельном файле, и поэтому не может получить доступ к экземпляру охватывающего класса.

Итак, чтобы обобщить то, что вам нужно сделать, либо сохранить класс вложенным, либо определить его как статичный:

public class YourActivity extends Activity {

    private static class OnCreateListenerImpl implements OnCreateListener {

        @Override
        public void onObjCreate() {
            Log.d("pltk", "dfgbfdgh");
        }
    }

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

        OnCreateListener inter = new OnCreateListenerImpl();
        Intent in = new Intent(Palatok.this, SecondActivity.class);
        in.putExtra("ob", inter);
        startActivity(in);
    }
}

Или вы можете переместить реализацию в отдельный файл:

public class OnCreateListenerImpl implements OnCreateListener {

    @Override
    public void onObjCreate() {
        Log.d("pltk", "dfgbfdgh");
    }
}

Хотя причина, по которой вы хотите отправить OnCreateListener в другую Activity все еще ускользает от меня, это должно решить вашу проблему.

Я надеюсь, что смогу помочь, и если у вас возникнут вопросы, не стесняйтесь спрашивать!