Java Android:如何将界面从一个活动发送到另一个活动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24780000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: How to send interface from one activity to another
提问by palatok
I have an interface like this:
我有一个这样的界面:
public interface MyInterface {
public void aMethod();
}
My custom Object:
我的自定义对象:
public class MyObject {
private Context context;
private MyInterface inter;
public MyObject(Context context) {
this.context = context;
this.inter = (MyInterface) this.context;
inter.aMethod();
}
}
MainActivity:
主要活动:
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();
}
}
Here, inside MyObject constructor i can get the interface from the context and then communicate with the Activity.
在这里,在 MyObject 构造函数中,我可以从上下文中获取接口,然后与 Activity 进行通信。
But how can i send interface from one activity to another ?
I need to call a method inside Activity1 from Activity2
Is there a way like this ?
但是如何将接口从一个活动发送到另一个活动?
我需要从 Activity2 调用 Activity1 中的一个方法
有这样的方法吗?
Note:i don't want to use fragment.
注意:我不想使用片段。
采纳答案by Xaver Kapeller
First and foremost, this is very bad:
首先,这是非常糟糕的:
this.inter = (MyInterface) this.context;
If you pass a context into the constructor which does not implement your interface your application will crash and it's easy to make such a mistake. So you see, this is very error prone, instead implement it like this:
如果您将上下文传递给未实现您的接口的构造函数,您的应用程序将崩溃,并且很容易犯这样的错误。所以你看,这很容易出错,而是像这样实现它:
public class MyObject {
private Context context;
private MyInterface inter;
public MyObject(Context context, MyInterface inter) {
this.context = context;
this.inter = inter;
inter.aMethod();
}
}
This way it's much safer, and cleaner.
这样,它更安全,更清洁。
To send the Object
to another Activity
make sure it implements Serializable
like this:
要将 发送Object
给另一个,请Activity
确保它实现Serializable
如下:
public interface MyInterface extends Serializable {
public void aMethod();
}
And now you can just add the interface as an extra to the Intent
which starts the other Activity
:
现在您可以将接口作为额外添加到Intent
启动另一个的接口Activity
:
Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("interface", inter);
startActivity(intent);
And in the OtherActivity
you can get the Object
from the Intent
like this:
而在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");
...
}
EDIT:
编辑:
When you do something like this in your Activity
you are creating an anonymous class:
当你在你做这样的事情时,Activity
你正在创建一个匿名类:
OnCreateListener inter = new OnCreateListener() {
@Override
public void onObjCreate() {
Log.d("pltk", "dfgbfdgh");
}
};
The thing about such an anonymous class is that they are not static, meaning you can still access methods and variables from the class in which this listener is nested. Internally the reason for this is that this new class keeps a reference to the instance of the class which created it, in your case the enclosing Activity
. This is a great thing and we use it all the time for OnClickListener
etc. But in your case it is a problem because you want to send this Object
to another Activity
. The internal reference to the old Activity
keeps it from being serialised and that is a good thing. If you could just send an Object
like that you would create memory leaks like crazy because of all the old references which the garbage collector cannot collect.
这种匿名类的问题在于它们不是静态的,这意味着您仍然可以从嵌套此侦听器的类中访问方法和变量。内部原因是这个新类保留对创建它的类的实例的引用,在您的情况下是封闭的Activity
. 这是一件很棒的事情,我们一直在使用它OnClickListener
。但在您的情况下,这是一个问题,因为您想将其发送Object
给另一个Activity
. 对旧的内部引用可以Activity
防止它被序列化,这是一件好事。如果你可以发送一个Object
类似的,你会因为垃圾收集器无法收集的所有旧引用而疯狂地造成内存泄漏。
The solution is pretty simple, you can either define the class in its own file or you can make the class static. Static in this context means that the class is essentially treated like it were in it's own separate file and therefore cannot access the instance of the enclosing class.
解决方案非常简单,您可以在自己的文件中定义该类,也可以使该类成为静态的。静态在此上下文中意味着该类基本上被视为在它自己的单独文件中,因此无法访问封闭类的实例。
So to summarise what you have to do is either keep the class nested and define it static like this:
所以总结一下你必须做的要么保持类嵌套并像这样定义它静态:
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);
}
}
Or you can move the implementation in its own separate file:
或者您可以将实现移动到它自己的单独文件中:
public class OnCreateListenerImpl implements OnCreateListener {
@Override
public void onObjCreate() {
Log.d("pltk", "dfgbfdgh");
}
}
Although the reason why you would want to send an OnCreateListener
to another Activity
still eludes me, this should solve your problem.
尽管您想将一个发送OnCreateListener
给另一个人的原因Activity
仍然无法解决,但这应该可以解决您的问题。
I hope I could help and if you have any further questions feel free to ask!
我希望我能帮上忙,如果您有任何其他问题,请随时提出!
回答by Stepango
It is possible but such kind of Activity <-> Activity interraction will cause memory leaks. You should use LocalBroadcastManager (http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html) instead.
这是可能的,但这种 Activity <-> Activity 交互会导致内存泄漏。您应该改用 LocalBroadcastManager ( http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html)。