Activity与其他Activity创建的线程之间如何通信
Posted
技术标签:
【中文标题】Activity与其他Activity创建的线程之间如何通信【英文标题】:How to communicate between Activity and Threads created by other Actvity 【发布时间】:2019-12-11 16:52:18 【问题描述】:当您有 2 个活动( A 和 B )并且 A 是 MainActivity 时,现在您启动您的应用程序并且 A 启动 B。 B 是一个 Dialog 与用户交互的活动,创建一个蓝牙连接和 2 个线程,1 个接收和一个发送。 现在,将信息从 A 发送到 B 的线程的最佳方式是什么,反之亦然?
一开始我用的是静态的WeakReference,但是听说这会导致很多问题,所以想求一个更通用的解决方案。
请记住,当从另一个 Activity 启动一个 Activity 时,您只能传递 Serializable Objs 和简单数据。所以不可能那样使用Handler。
这是我使用的静态 WeakReference:
public class T1 extends Thread
private static WeakReference<T1> weak_T1;
public void T1 ()
weak_T1 = new WeakReference<T1> (This);
public static WeakReference getWeakReverence()
return weak_T1;
这是一种在堆栈中查找正在运行的线程的方法:
for (Thread thread : Thread.getAllStackTraces().keySet())
if (thread.getName().equalsIgnoreCase("T1"))
T1A =thread;
else if (thread.getName().equalsIgnoreCase("T2"))
T2A =thread;
也可能的解决方案:
public class example extends Thread
private static example instance;
private example()
public static example getIsntance()
if(instance == null)
instance = new example();
return instance;
【问题讨论】:
只是好奇,如何防止系统在 Activity B 显示时破坏 Activity A? @greeble31 A 是 B 的父级,所以 A 只是 onPause 而不是 onDestroy。或者也许我不明白你的问题,但为什么 A 应该被破坏? @greeble31 明确一点,线程启动后,活动 B 完成,A 再次处于前台。 我的意思是,你不能保证活动 A 保持在“暂停”状态(或者实际上是“停止/隐藏”,在这种情况下,状态)任何长度时间。正如docs 中提到的,停止的活动“......当其他地方需要内存时,通常会被系统杀死”。尝试与屏幕外 Activity 进行通信是不行的。您需要将线程结果保存在某处(例如 Service 甚至静态引用),然后让 Activity A 在恢复后获取该信息。 您如何看待“get Thread in Stack”解决方案?风险是得到一个空指针异常,但我想不出其他问题。 【参考方案1】:WeakReference
可能不是您想要的,在这里。也就是说,假设您的 Thread 对象要么没有终止,要么在 Activity B 停止后以某种方式维护一些对 Activity A 有用的信息。如果您使用WeakReference
,它可能会在活动 B 结束后立即变为“null”,并且线程终止。只需使用常规的旧强引用。它将确保 T1 和包含的信息继续存在,直到您完成它为止。
public class ActivityB extends Activity
private T1 t1;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
t1 = startMyThread();
@Override
public void onBackPressed()
ActivityA.tempT1 = t1;
//This technique presumes that Activity A is guaranteed to resume after a
//back button press, based on the arrangement of your backstack, etc. If
//Activity A is started via some other means (e.g., an explicit startActivity(),
//finish(), etc.), then this reference will have to be set prior to
//that call, as well, in order to establish the appropriate "happens before" relationship.
//If you fail to ensure that Activity A resumes after this point, you will
//risk a memory leak.
super.onBackPressed();
public class ActivityA extends Activity
public static T1 tempT1 = null;
private T1 t1;
@Override
public void onResume()
super.onResume();
if(tempT1 == null)
//Apparently, Activity B hasn't executed yet. Provide the user with a button to start it.
else
t1 = tempT1;
tempT1 = null; //To avoid a memory leak
//We just retrieved the reference that Activity B left for us.
//Now, change UI states so that the user can see information about t1.
【讨论】:
由于每个活动都通过 onResume() 我们可以通过这种方式在活动之间传递几乎所有内容吗?例如处理程序。 是的,我个人从不这样做(我使用Service
b/c,因为其他原因需要它)但只要你能建立“发生在之前”的关系,这是安全的。
感谢您的帮助。祝你有美好的一天。
只是为了完成这个:如果我们在 Manifest 中设置一个 ParentActivity,我们可以确定,在 Activity B 完成后,哪个 Activity 将被启动(恢复或创建)。 look at android:parentActivityName
您能否添加一个示例,如何从 A 创建后台服务(任何扩展 Service.class)以及如何将 A 和 B 绑定到它?我知道你已经回答了这个问题,但这真的很有帮助:)以上是关于Activity与其他Activity创建的线程之间如何通信的主要内容,如果未能解决你的问题,请参考以下文章
Android四大组件之Activity(活动)及其布局的创建与加载布局
Android 插件化Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )