活动到活动回调监听器

Posted

技术标签:

【中文标题】活动到活动回调监听器【英文标题】:activity to activity callback listener 【发布时间】:2016-02-25 10:44:38 【问题描述】:

假设有两个活动Activity1Activity2。我需要从methodAct2Activity2 内部)调用方法methodAct1()Activity1 内部)。我认为它应该使用回调侦听器工作 - 我不想使用 EventBus libs!

我使用此代码得到java.lang.NullPointerException

界面:

public interface MyListener 
    public void listen();

创建事件的活动:

public class Activity2 extends Activity 

    private MyListener  myListener;

    public void setUpListener(MyListener myListener) 
        this.myListener = myListener;
    

    private void doWork()
        //do stuff 
        myListener.listen();
    

我希望在工作完成后获得该事件的活动:

public class Activity1 extends Activity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        Activity2 activity2 = new Activity2();
        activity2.setUpListener(new setUpListener() 
            @Override
            public void listen() 
                // get the event here

            
        );
    

【问题讨论】:

但一次只有一个活动被初始化,您应该在一个意图中发送一些数据并启动另一个活动并读取该数据或可能使用 startActivityForResult 你只是提到了接口,但你的活动都没有实现它 为什么要用构造函数实例化Activity?这不是这样做的方法。要开始一个新的活动,你必须创建一个Intent 并调用startActivity() @Sarthak Mittal 我不需要在第二个工作完成后初始化第一个,只需在那里运行一些代码 @VasileDoe 先加强你的基础然后你就会明白了:) 【参考方案1】:

这是绝对不可能的。你永远不会自己实例化一个新的 Activity。您不会同时运行两个活动。

如果您希望另一个 Activity 根据您之前的 Activity 想要做某事,那么您需要将其添加到您的 Intent 中。

Intent intent = new Intent(this, Activity2.class);
intent.putExtra("data field", "data value");
startActivity(intent);

如果您希望通过回调实现特定功能,那么您可能会考虑Fragments。通过这种方式,您可以运行相同的 Activity,它可以告诉各个 Fragment 他们需要做什么。

【讨论】:

是的,也许这是解决我的情况最简单的方法,但我已经改变了一点逻辑以适应这个解决方案 否决票,是的,是的,是的——这被称为检测:)——你可以驱动每个活动实例化和整个应用程序实例化 您不是自己创建它,但关键是,使用new 关键字。这是给出的问题的关键问题。对于 Activity 检测,您通常会使用 ActivityInstrumentationTestCase2 之类的东西。【参考方案2】:

由于您的陈述,NPE 正在发生:

Activity2 activity2 = new Activity2(); <--

你不应该这样做,而是应该在活动 1 中这样做:

Intent intent = new Intent(this, Activity2.class);
intent.putExtra("dataKey", "dataValue");
startActivityForResult(pickContactIntent, CALLBACK_REQUEST);

startActivityForResult() 提供从 Activity 2 到 Activity 1 的回调,您必须覆盖 Activity 1 中的结果:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    // Check which request we're responding to
    if (requestCode == CALLBACK_REQUEST) 
        // Make sure the request was successful
        if (resultCode == RESULT_OK) 
            // The Intent's data Uri identifies which contact was selected.

            // Do something with the contact here (bigger example below)
        
    

【讨论】:

【参考方案3】:

你可以像这样用你的方法做到这一点......

public class Activity2 extends AppCompatActivity 

    private static MyListener  myListener;

    public static void setUpListener(MyListener Listener) 
        myListener = Listener;
    

    public void doWork(View view) 
        myListener.listen();
    



public class Activity1 extends AppCompatActivity 

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

        Activity2.setUpListener(new MyListener() 
            @Override
            public void listen() 
                Log.d("Hello", "Hello World");
            
        );
    

    public void goToAnotherActivity(View view) 
        startActivity(new Intent(Activity1.this, Activity2.class));
    

虽然这不是最好的方法,但为了使用这种机制,您需要创建 activity1。

【讨论】:

这在 Activity2 由于静态 myListener 而被多次打开的情况下不起作用,例如在导航堆栈中。 android 范式根本不使用这样的概念。如果一个人试图逆水而行,就会引发各种各样的问题,最终导致代码变得脆弱且难以维护。【参考方案4】:

你可以这样做> - STEP 01:实现共享接口


public interface SharedCallback 
    public String getSharedText(/*you can define arguments here*/);

步骤 02:实现共享类
final class SharedMethode 
    private static Context mContext;

    private static SharedMethode sharedMethode = new SharedMethode();

    private SharedMethode() 
        super();
    

    public static SharedMethode getInstance() 
        return sharedMethode;
    

    public void setContext(Context context) 
        if (mContext != null)
            return;

        mContext = context;
    

    public boolean contextAssigned() 
        return mContext != null;
    

    public Context getContext() 
        return mContext;
    

    public void freeContext() 
        mContext = null;
    

- STEP 03 :: 在第一个活动中玩代码


public class FirstActivity extends Activity implements SharedCallback 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);

        // call playMe from here or there
        playMe();
    

    private void playMe() 
        SharedMethode.getInstance().setContext(this);
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
    

    @Override
    public String getSharedText(/*passed arguments*/) 
        return "your result";
    


步骤 04 :: 在 SecondActivity 中完成游戏
public class SecondActivity extends Activity 

    private SharedCallback sharedCallback;

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

        if (SharedMethode.getInstance().contextAssigned()) 
            if (SharedMethode.getInstance().getContext() instanceof SharedCallback)
                sharedCallback = (SharedCallback) SharedMethode.getInstance().getContext();

            // to prevent memory leak. no further needs
            SharedMethode.freeContext();
        

        // You can now call your implemented methodes from anywhere at any time
        if (sharedCallback != null)
            Log.d("TAG", "Callback result = " + sharedCallback.getSharedText());

    

        @Override
        protected void onDestroy() 
        sharedCallback = null;
        super.onDestroy();
    


你也可以实现一个 backword 回调(从 First 到 Second)来从 SecondAvtivity 中获取一些结果或者调用一些方法

【讨论】:

通过这种方式,您可以从 mainActivity 共享全局变量或从 mainActivity 发布更新到任何前台活动。 这是一个糟糕的解决方案。这只有效,因为它泄漏了Activity。当框架决定销毁您的进程并稍后恢复它时,它也不起作用。在这种情况下,SecondActivity 将被恢复,但FirstActivity 永远不会被调用(SharedMethode.mContext 将为空)。

以上是关于活动到活动回调监听器的主要内容,如果未能解决你的问题,请参考以下文章

在活动之间发送监听器

从另一个活动调用时为空侦听器

Android监听器/回调如何?

将数据从片段发送到活动,无需任何事件处理或侦听器

如何将结果数据从广播接收器发送到活动

何时在addSnapshotListener中使用getActivity?