Android:如何将接口从一个活动发送到另一个活动

pal*_*tok 25 java android interface android-activity

我有这样的界面:

public interface MyInterface {
    public void aMethod();
}
Run Code Online (Sandbox Code Playgroud)

我的自定义对象:

public class MyObject {

    private Context context;
    private MyInterface inter;

    public MyObject(Context context) {
        this.context = context;
        this.inter = (MyInterface) this.context;
        inter.aMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

主要活动:

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();
    }
}  
Run Code Online (Sandbox Code Playgroud)

在MyObject构造函数中,我可以从上下文中获取接口,然后与Activity通信.

但是,如何将界面从一个活动发送到另一个活动?
我需要从Activity2调用Activity1中的方法
有这样的方法吗?

注意:我不想使用片段.

Xav*_*ler 42

首先,这是非常糟糕的:

this.inter = (MyInterface) this.context;
Run Code Online (Sandbox Code Playgroud)

如果将上下文传递给未实现接口的构造函数,则应用程序将崩溃并且很容易出错.所以你看,这很容易出错,而是像这样实现它:

public class MyObject {

    private Context context;
    private MyInterface inter;

    public MyObject(Context context, MyInterface inter) {
        this.context = context;
        this.inter =  inter;
        inter.aMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样它更安全,更清洁.


要发送Object给另一个,请Activity确保它实现Serializable如下:

public interface MyInterface extends Serializable {
    public void aMethod();
}
Run Code Online (Sandbox Code Playgroud)

现在你可以将界面作为额外添加到Intent另一个启动另一个Activity:

Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("interface", inter);
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

而在OtherActivity你可以得到ObjectIntent这样的:

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

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

编辑:

当你在你做的事情中,Activity你正在创建一个匿名类:

OnCreateListener inter = new OnCreateListener() {

    @Override
    public void onObjCreate() {
        Log.d("pltk", "dfgbfdgh");
    }
};
Run Code Online (Sandbox Code Playgroud)

关于这样一个匿名类的事情是它们不是静态的,这意味着你仍然可以从嵌套这个监听器的类中访问方法和变量.在内部,原因是这个新类保留了对创建它的类的实例的引用,在您的情况下是封闭的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者您可以将实现移动到其自己的单独文件中:

public class OnCreateListenerImpl implements OnCreateListener {

    @Override
    public void onObjCreate() {
        Log.d("pltk", "dfgbfdgh");
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然你想要发送OnCreateListener给另一个的原因Activity仍然无法解决,但这应该可以解决你的问题.

我希望我能提供帮助,如果您有任何其他问题,请随时提出!

  • 把它编辑成你的问题,不要链接到它...无论如何错误就在日志中:`引起:java.io.NotSerializableException:com.example.palatok.Palatok`.`com.example.palatok.Palatok`是你的"活动"吗? (2认同)
  • 这是不可能的,因为“Serialized”接口不能像这样传递,因为它的父类可能不可序列化。它很可能会导致崩溃。 (2认同)