两个 Android 活动之间通过引用调用者或被调用者进行通信
Communication Between Two Android Activities via Reference to Caller or Callee
我在同一个应用程序中有两个活动 Activity A 和 Activity B,它们需要能够相互调用方法。 A 需要在开始时与 B 通信(可能见下文 "code")。
B会在A上调用很多方法(这意味着我不能使用startActivityForResult方法进行通信,因为这会关闭B(ActivityB是蓝牙客户端和服务器因为它是点对点应用程序))。我确实使用 startActivityForResult 来启动 B 以获得比任何结果都更多的终止信号。
Activity A 使用 SupportMapFragment 并且 Activity B 不能是一个片段,因为我希望能够从 B 切换到 A,然后不再使用 B。
最初,我从一个 activity 开始,并尝试使用 ViewFlipper 和仅调用 setContentView(R.layout.my_layout_A) 或 setContentView(R.layout.my_layout_B) 在视图之间切换。片段当然给双方都带来了很多问题。
使用 Fragments 令人困惑。 SupportMapFragment 是 Google 地图的代码,它是一个片段。
当我点击 MapsActivity 中的菜单选项时 (Activity A),我希望能够启动 myBluetoothActivity (Activity B ) 引用 MapsActivity (Activity A) 或启动 myBluetoothActivity 然后能够在 myBluetoothActivity 中设置对调用者的引用(但这选项需要在 MapsActivity 中引用 BluetoothActivity 或通过某种方式从 intent 中获取启动的 activity)。
//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)
如何通过两个活动之间的引用来实现这两个活动之间的通信?我应该使用接口进行通信吗?如果我应该使用它,(我确实尝试过)我应该怎么做?
换句话说,我试图通过对内部 Activity A 的引用直接从 (Activity B) 访问调用者 activity (Activity A) B 或尝试从 Activity A 内部启动它的意图获取对 B 的引用。我正在尝试获取对此的引用,因此我可以将其用于 communication/method calling/member 变量和 UI 修改目的。
注意:1. 蓝牙Activity 和地图Activity 不可序列化。我尝试对其进行序列化,然后将其添加到 Intent 中的 extras Bundle 中,但它崩溃了,说由于 BroadCastReciever 而无法序列化。因为这也涉及 WIFI。我非常考虑在未来的版本中将其与蓝牙Activity分开。
我还假设 Activity B 永远不会被我的地图以外的任何东西启动Activity class.
我也是Kotlin新手,但我知道Java。
当我尝试使用界面时,我导致了 Whosebug 错误,我不知道为什么。
我已阅读网站上的 Intents 文档。
我在这里做了一些研究,这给了我上面的那些想法。我不确定如何实现它们。
您使用了错误的方法。该解决方案需要比您想象的更多的工作。正确的做法是:
首先,要意识到这些活动 Activity A 和 Activity B(以及任何其他活动)是特定于您的应用程序的活动,您希望在它们之间建立直接通信。
其次,意识到您正在尝试获取当前(或之前)activity 的上下文。上下文将有助于提供参考。
第三,您可以通过扩展所需的 classes 创建自己的 Activity 和 Application classes。应用程序 class 是用于活动的低级别 class。
从这里开始,您将能够使用 getApplicationContext(),它将 return 您的自定义应用程序 class。
设计:在您的 CustomApplication class 内部,您必须跟踪对所需活动的引用。从那里,您所要做的就是将 getApplicationContext() 转换为您的 CustomApplication class,然后调用访问 Activity(ies) 的方法。如果你想访问你创建的特定 activity 的某些实例到它的 "type." 例如:
MapsActivity mact = (MapsActivity)(((MyApplication)(this.getApplicationContext())).getCurrentActivity())
你当然要注意这个activity必须已经创建(onCreate方法已经被调用)为了return当前activity。 activity 的其他生命周期方法当然也是如此,因为您将创建一个 baseActivity 来处理这些方法,并且您还将拥有一个应用程序生命周期,这将有助于也处理这个。
为了回答这个问题:"How to get the current foreground activity context in android?" 我求助于 Whosebug,发现用户:gezdy 的答案正是我在 How to get current foreground activity context in android?.
上所需要的
(开始引用:GEZDY)
You should manage activities references. Add the name of the
application in the manifest file :
<application
android:name=".MyApp"
....
</application>
Your application class :
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;
}
}
Create a new Activity :
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);
}
}
So, now instead of extending Activity class for your activities, just
extend MyBaseActivity. Now, you can get your current activity from
application or Activity context like that :
Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();
(引用结束:GEZDY)
注:本答案的所有代码都写在java中。
我在同一个应用程序中有两个活动 Activity A 和 Activity B,它们需要能够相互调用方法。 A 需要在开始时与 B 通信(可能见下文 "code")。
B会在A上调用很多方法(这意味着我不能使用startActivityForResult方法进行通信,因为这会关闭B(ActivityB是蓝牙客户端和服务器因为它是点对点应用程序))。我确实使用 startActivityForResult 来启动 B 以获得比任何结果都更多的终止信号。
Activity A 使用 SupportMapFragment 并且 Activity B 不能是一个片段,因为我希望能够从 B 切换到 A,然后不再使用 B。
最初,我从一个 activity 开始,并尝试使用 ViewFlipper 和仅调用 setContentView(R.layout.my_layout_A) 或 setContentView(R.layout.my_layout_B) 在视图之间切换。片段当然给双方都带来了很多问题。
使用 Fragments 令人困惑。 SupportMapFragment 是 Google 地图的代码,它是一个片段。
当我点击 MapsActivity 中的菜单选项时 (Activity A),我希望能够启动 myBluetoothActivity (Activity B ) 引用 MapsActivity (Activity A) 或启动 myBluetoothActivity 然后能够在 myBluetoothActivity 中设置对调用者的引用(但这选项需要在 MapsActivity 中引用 BluetoothActivity 或通过某种方式从 intent 中获取启动的 activity)。
//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)
如何通过两个活动之间的引用来实现这两个活动之间的通信?我应该使用接口进行通信吗?如果我应该使用它,(我确实尝试过)我应该怎么做?
换句话说,我试图通过对内部 Activity A 的引用直接从 (Activity B) 访问调用者 activity (Activity A) B 或尝试从 Activity A 内部启动它的意图获取对 B 的引用。我正在尝试获取对此的引用,因此我可以将其用于 communication/method calling/member 变量和 UI 修改目的。
注意:1. 蓝牙Activity 和地图Activity 不可序列化。我尝试对其进行序列化,然后将其添加到 Intent 中的 extras Bundle 中,但它崩溃了,说由于 BroadCastReciever 而无法序列化。因为这也涉及 WIFI。我非常考虑在未来的版本中将其与蓝牙Activity分开。
我还假设 Activity B 永远不会被我的地图以外的任何东西启动Activity class.
我也是Kotlin新手,但我知道Java。
当我尝试使用界面时,我导致了 Whosebug 错误,我不知道为什么。
我已阅读网站上的 Intents 文档。
我在这里做了一些研究,这给了我上面的那些想法。我不确定如何实现它们。
您使用了错误的方法。该解决方案需要比您想象的更多的工作。正确的做法是:
首先,要意识到这些活动 Activity A 和 Activity B(以及任何其他活动)是特定于您的应用程序的活动,您希望在它们之间建立直接通信。
其次,意识到您正在尝试获取当前(或之前)activity 的上下文。上下文将有助于提供参考。
第三,您可以通过扩展所需的 classes 创建自己的 Activity 和 Application classes。应用程序 class 是用于活动的低级别 class。
从这里开始,您将能够使用 getApplicationContext(),它将 return 您的自定义应用程序 class。
设计:在您的 CustomApplication class 内部,您必须跟踪对所需活动的引用。从那里,您所要做的就是将 getApplicationContext() 转换为您的 CustomApplication class,然后调用访问 Activity(ies) 的方法。如果你想访问你创建的特定 activity 的某些实例到它的 "type." 例如:
MapsActivity mact = (MapsActivity)(((MyApplication)(this.getApplicationContext())).getCurrentActivity())
你当然要注意这个activity必须已经创建(onCreate方法已经被调用)为了return当前activity。 activity 的其他生命周期方法当然也是如此,因为您将创建一个 baseActivity 来处理这些方法,并且您还将拥有一个应用程序生命周期,这将有助于也处理这个。
为了回答这个问题:"How to get the current foreground activity context in android?" 我求助于 Whosebug,发现用户:gezdy 的答案正是我在 How to get current foreground activity context in android?.
上所需要的(开始引用:GEZDY)
You should manage activities references. Add the name of the application in the manifest file :
<application android:name=".MyApp" .... </application>
Your application class :
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; } }
Create a new Activity :
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); } }
So, now instead of extending Activity class for your activities, just extend MyBaseActivity. Now, you can get your current activity from application or Activity context like that :
Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();
(引用结束:GEZDY)
注:本答案的所有代码都写在java中。