【问题标题】:Communication Between Two Android Activities via Reference to Caller or Callee两个 Android Activity 之间通过引用 Caller 或 Callee 进行通信
【发布时间】:2018-05-22 06:55:31
【问题描述】:

我在同一个应用程序中有两个活动 Activity A 和 Activity B,它们需要能够相互调用方法。 A 需要在开始时与 B 通信(可能参见下面的“代码”)。

B 会在 A 上调用很多方法(这意味着我不能使用 startActivityForResult 方法进行通信,因为这会关闭 B(Activity B 是蓝牙客户端和服务器,因为它是点对点应用程序))。我确实使用 startActivityForResult 来启动 B 以获得更多的终止信号而不是结果。

Activity A 使用 SupportMapFragment,而 Activity B 不能是片段,因为我希望能够从 B 切换到 A,然后不再使用 B。

最初,我从一项活动开始,并尝试使用 ViewFlipper 在视图之间切换,只需调用 setContentView(R.layout.my_layout_A) 或 setContentView(R.layout.my_layout_B)。片段当然给双方带来了很多问题。

使用 Fragment 令人困惑。 SupportMapFragment 是谷歌地图的代码,它是一个片段。

当我单击 MapsActivity(活动 A)内的菜单选项时,我希望能够启动 myBluetoothActivity(活动 B)并引用 MapsActivity(活动 A)或启动 myBluetoothActivity,然后能够设置对 myBluetoothActivity 内的调用者的引用(但此选项需要引用 MapsActivity 内的 BluetoothActivity 或有某种方式从 Intent 中获取已启动的活动)。

//the following code is in Kotlin, but this can easily be converted over to java:
//option A: (pass it inside of the constructor)
var mbta:myBluetoothActivity = myBluetoothActivity(this)
//line for intent that I am unsure of
//intent so that I can start the activity with the pointer to the caller already passed into the new activity
startActivity(mbta)

//option B: (set this reference after obtaining a reference from intent):
var mintent:Intent = Intent(this.applicationContext, myBluetoothActivity::class.java)
startActivity(mintent)
//obtain the reference to the BluetoothActivity from the intent (NOT SURE HOW TO DO THIS???)
mbta.setCallerReference(this)

如何通过两个活动之间的引用来完成两个活动之间的这种通信?我应该使用接口进行通信吗?如果我应该使用它,(我确实尝试过)我应该怎么做?

换句话说,我试图通过对 B 内部的 Activity A 的引用直接从 (Activity B) 访问调用者活动 (Activity A),或者试图从启动它的 Intent 中获取对 B 的引用活动 A。我正在尝试获取对它的引用,因此我可以将其用于通信/方法调用/成员变量和 UI 修改目的。

注意: 1. BluetoothActivity 和 MapsActivity 不可序列化。我尝试对其进行序列化,然后将其添加到 Intent 中的 extras Bundle 中,但它只是崩溃了,说由于 BroadCastReciever 而无法序列化。因为这也涉及WIFI。我高度考虑将其分离出来,以便在未来的版本中与 BluetoothActivity 一起使用。

  1. 我还假设 Activity B 永远不会被 MapsActivity 类以外的任何东西启动。

  2. 我也是 Kotlin 的新手,但我懂 Java。

  3. 当我尝试使用接口时,我导致了 StackOverflow 错误,我不知道为什么。

  4. 我已阅读网站上的 Intent 文档。

  5. 我在这里做了一些研究,这给了我上面的想法。我不确定如何实现它们。

【问题讨论】:

  • 一次只能看到一个活动,但它们的实例仍保留在内存中(至少在一个启动另一个后的最初几分钟内)。第一个 Activity A MapsActivity 是可见的,然后蓝牙的 Activity B 在隐藏 A 时是可见的(假设它启动)。活动 A 是应用程序的主要活动。活动 B 只是充当帮助者。我希望能够对主要活动进行更改,即使它驻留在后台以及对用户可见以及与用户交互时也是如此。

标签: java android android-fragments kotlin communication


【解决方案1】:

您使用了错误的方法。该解决方案需要比您想象的更多的工作。正确的做法是:

首先,请意识到这些活动 Activity A 和 Activity B(以及任何其他活动)是特定于您的应用程序的活动,并且您希望在它们之间建立直接通信。

其次,意识到您正在尝试获取当前(或先前)活动的上下文。上下文将有助于提供参考。

第三,您可以通过扩展所需的类来创建自己的 Activity 和 Application 类。 Application 类是用于活动的低级类。

从这里,您将能够使用 getApplicationContext(),它将返回您的自定义 Application 类。

设计:在您的 CustomApplication 类中,您必须跟踪对所需活动的引用。从那里您所要做的就是将 getApplicationContext() 转换为您的 CustomApplication 类,然后调用访问 Activity(ies) 的方法。如果您想访问您创建的特定活动的某些实例,那么您当然必须将您的活动转换为它的“类型”。例如:

MapsActivity mact = (MapsActivity)(((MyApplication)(this.getApplicationContext())).getCurrentActivity())

您当然必须注意,此活动必须已创建(已调用 onCreate 方法)才能返回当前活动。当然,活动的其他生命周期方法也是如此,因为您将创建一个 baseActivity 来处理这些方法,并且您还将拥有一个应用程序生命周期来帮助处理这些问题。

回答问题:“如何在android中获取当前的前台活动上下文?”我转向 StackOverflow,发现 user: gezdy 的答案正是我所需要的:How to get current foreground activity context in android?。

(开始报价来自:GEZDY)

您应该管理活动引用。添加名称 清单文件中的应用程序:

 <application
    android:name=".MyApp"
    ....
 </application>

您的应用程序类:

public class MyApp extends Application {
     public void onCreate() {
          super.onCreate();
     }

     private Activity mCurrentActivity = null;
     public Activity getCurrentActivity(){
          return mCurrentActivity;
     }
     public void setCurrentActivity(Activity mCurrentActivity){
          this.mCurrentActivity = mCurrentActivity;
     }
}

创建一个新的活动:

public class MyBaseActivity extends Activity {
    protected MyApp mMyApp;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMyApp = (MyApp)this.getApplicationContext();
    }
    protected void onResume() {
        super.onResume();
        mMyApp.setCurrentActivity(this);
    }
    protected void onPause() {
        clearReferences();
        super.onPause();
    }
    protected void onDestroy() {        
        clearReferences();
        super.onDestroy();
    }
    private void clearReferences(){
        Activity currActivity = mMyApp.getCurrentActivity();
        if (this.equals(currActivity))
            mMyApp.setCurrentActivity(null);
    }
}

所以,现在不要为您的活动扩展 Activity 类,只需 扩展 MyBaseActivity。现在,您可以从 像这样的应用程序或活动上下文:

Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();

(来自:GEZDY 的报价结束)

注意:此答案的所有代码都是用 java 编写的。

【讨论】:

    猜你喜欢
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    相关资源
    最近更新 更多