资讯专栏INFORMATION COLUMN

Activity跳转时传递数据的骚操作

alphahans / 3491人阅读

摘要:一不小心隔了大半年没有写博客了,这大半年从一个小菜鸡变成了一个大菜鸡。。。

一不小心隔了大半年没有写博客了,这大半年从一个小菜鸡变成了一个大(pang)菜鸡。。。好吧,进入正题吧

Q:MainActivity跳到TargetActivity时附带数据要怎么做?

A:不就是intent附带数据吗?或者sp/文件存一下等等方式....

Q:那如果是没有实现序列化的数据呢?

A:序列化一下呗...

Q:业务原因/历史原因....这个Bean类要实现序列化的话牵扯到太多东西了,改动成本太大,例如:Bean类里面有Data类,Data类里面又有Other类........这样的问题

A:..???..???...????!!!!!??!

开始埋头苦想

这埋的雷够巧妙啊,不过难不倒我,这个灵机一动动~诶,我可以这样做:

</>复制代码

  1. 在跳转的时候,先用一个静态变量引用数据,等TargetActivity起来的时候,再把静态变量置为null,哎呀,一不小心还注意到了要避免内存泄漏,太棒了!

</>复制代码

  1. public class TargetActivity extends AppCompatActivity {
  2. // 临时承载数据
  3. private static Bean sBean;
  4. // activity起来的时候真正引用到数据
  5. private Bean mBean;
  6. /**
  7. * 启动TargetActivity必须统一走这个方法
  8. * @param context c
  9. * @param bean bean
  10. */
  11. public static void start(Context context, Bean bean) {
  12. Intent starter = new Intent(context, TargetActivity.class);
  13. // 静态变量先拿着
  14. sBean = bean;
  15. context.startActivity(starter);
  16. }
  17. {
  18. // 成员变量拿到引用
  19. mBean = sBean;
  20. // 静态变量置空,防止内存泄漏
  21. sBean = null;
  22. }
  23. @Override
  24. protected void onCreate(@Nullable Bundle savedInstanceState) {
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.activity_target);
  27. Log.i("LiuZh", "onCreate: " + mBean.name + " " + mBean.age);
  28. }
  29. }

总感觉这种拍脑袋就搞出来的骚操作有点不太对劲啊

对了!如果有两个地方依次相接调用TargetActivity.start(Context,Bean)方法,第一个start调用还没开始创建activity呢,第二个start就把sBean重新赋值了,那两个activity就拿到了同一个数据.....不行,这样就乱了,得规避一下这问题---(至于有没有允许启动多个相同activity的需求,反正我有....也总会有的)

这样的话,我可以把start方法锁住,然后执行完了sBean = null;这个语句再解锁?

那要怎么写呢,那就给start方法加个synchronized吧,startActivity语句走完就阻塞住,等activity起来拿到数据的时候就解阻塞,好像可以

接下来就是,要怎么阻塞呢?而且阻塞的话千万不能在主线程,也就意味着我需要在子线程内锁代码块,在子线程内阻塞。这样的话,就在子线程用一个while(flag)吧,activity拿完数据就修改flag通知一下,哦了,啪啪就是敲

</>复制代码

  1. public class TargetActivity extends AppCompatActivity {
  2. // 临时承载数据
  3. private static Bean sBean;
  4. // activity起来的时候真正引用到数据
  5. private Bean mBean;
  6. private static boolean sNextStartTaskFlag = false;
  7. /**
  8. * 启动TargetActivity必须统一走这个方法
  9. *
  10. * @param context c
  11. * @param bean bean
  12. */
  13. public static void start(final Context context, final Bean bean) {
  14. new Thread() {
  15. @Override
  16. public void run() {
  17. super.run();
  18. synchronized (TargetActivity.class) {
  19. sNextStartTaskFlag = false;
  20. Intent starter = new Intent(context, TargetActivity.class);
  21. // 静态变量先拿着
  22. sBean = bean;
  23. context.startActivity(starter);
  24. // 阻塞住
  25. while (!sNextStartTaskFlag) ;// do nothing
  26. }
  27. }
  28. }.start();
  29. }
  30. {
  31. // 成员变量拿到引用
  32. mBean = sBean;
  33. // 静态变量置空,防止内存泄漏
  34. sBean = null;
  35. // 我ok了, 下一个start可以走了
  36. sNextStartTaskFlag = true;
  37. }
  38. @Override
  39. protected void onCreate(@Nullable Bundle savedInstanceState) {
  40. super.onCreate(savedInstanceState);
  41. setContentView(R.layout.activity_target);
  42. Log.i("LiuZh", "onCreate: " + mBean.name + " " + mBean.age);
  43. }
  44. }

得,这样应该没啥问题了,走你

MainActivity布局

</>复制代码

MainActivity

</>复制代码

  1. public class MainActivity extends AppCompatActivity {
  2. private Activity mContext;
  3. private Bean mBean = new Bean();
  4. {
  5. mContext = this;
  6. mBean.name = "LiuZh";
  7. mBean.age = 22;
  8. }
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13. }
  14. public void startTargetActivity(View view) {
  15. TargetActivity.start(mContext, mBean);
  16. }
  17. }

走你

哦哟,好像还挺不错的,好,作为一个有追求的小码渣,还是来自测一下吧,用多个线程来疯狂调用一下的start方法:

</>复制代码

  1. public void startTargetActivity(View view) {
  2. new Thread(new Runnable() {
  3. @Override
  4. public void run() {
  5. for (int i = 0; i < 2; i++) {
  6. Bean bean = new Bean();
  7. bean.name = "thread_1_LiuZh_" + i;
  8. bean.age = i;
  9. TargetActivity.start(mContext, bean);
  10. Log.i("LiuZh", "Thread_1: " + i);
  11. }
  12. }
  13. }).start();
  14. new Thread(new Runnable() {
  15. @Override
  16. public void run() {
  17. for (int i = 0; i < 2; i++) {
  18. Bean bean = new Bean();
  19. bean.name = "thread_2_LiuZh_" + i;
  20. bean.age = i;
  21. TargetActivity.start(mContext, bean);
  22. Log.i("LiuZh", "Thread_2: " + i);
  23. }
  24. }
  25. }).start();
  26. new Thread(new Runnable() {
  27. @Override
  28. public void run() {
  29. for (int i = 0; i < 2; i++) {
  30. Bean bean = new Bean();
  31. bean.name = "thread_3_LiuZh_" + i;
  32. bean.age = i;
  33. TargetActivity.start(mContext, bean);
  34. Log.i("LiuZh", "Thread_3: " + i);
  35. }
  36. }
  37. }).start();
  38. }

走你

哦了,从Log看起来没问题了,看看是不是有6个activity起来了吧,看模拟器去吧

啥?图?

没图!自个跑一遍吧

结语

</>复制代码

  1. 更多内容欢迎访问我的主页我的博客

  2. 觉得本文/本Demo对你有所帮助,请不要忘了点一下文末的"♡"让他变成"❤"

  3. 文中有不妥/错误之处,还请见谅并指出

  4. 学习就是耐住寂寞不断踩坑,多动手敲就能有更多的知识经验和肩椎脊柱受损T_T

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/68423.html

相关文章

  • 当微信小程序遇上filter~

    摘要:具体用法其中表示数组元素的值,表示数组元素的下标,表示包含该元素的数组。这里采用随机函数来获取数组的下标,函数是获取之间的数,函数是向下取整,这样就可以随机获取相应的下标数。小程序中的模板就很好地帮我们解决了这个问题,并通过属性来实现调用。 在微信小程序的开发过程中,当你想要实现不同页面间的数据绑定,却为此抓耳饶腮时,不妨让微信小程序与filter 来一场完美的邂逅,相信会给你带来别样...

    Darkgel 评论0 收藏0
  • MVPArms官方快速组件化方案开源,来自5K star的信赖

    摘要:原文地址前言起源组件化方案分析业务组件的划分和代码隔离路由框架基础库的优势简介什么是组件化为什么要组件化分析现有的组件化方案如何选择组件化方案组件化方案描述架构图一览架构图详解宿主层业务层业务模块的拆分基础层核心基础业务公共服务基础组件其他 原文地址: https://www.jianshu.com/p/f67... 0 前言 0.1 起源 0.2 组件化方案分析 0.2....

    aikin 评论0 收藏0
  • Android开发艺术探索--Activity

    摘要:的控制又来控制一个栈和其状态。但是当变化发生的时候,将会有一个回调函数被执行。。前一个仍然保留在返回栈当中,但会处于停止状态。 接下来根据自己的平时的学习和自己最近要读的两本书《android开发艺术探索》和《android群英传》来梳理记录下自己的学习过程和对于遇到问题如何处理解决,还有将会陆续下一些有关关于如何将Java代码写的更优雅的,结合自己读过的书来做个记录整理型的系列博客。...

    ephererid 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<