老生常谈之Android 启动模式

关于启动模式网上一堆一堆的文章可以参考,我只是通过自己实践记录一下实验过程

tip1 adb shell

dumpsys | grep "DUMP OF SERVICE"  //列举当前手机所有支持的dumpsys命令
查看activity 堆栈
dumpsys activity 包名

找到 Running activities (most recent first): 这一行下面的就是task信息

Task

  1. Task 是一个堆栈。里面维护了一系列Activity
  2. 不同应用的Activity 可以包含在一个Task 里边,比如系统发送邮件等等

实验1 在一个app中建立两个Task

  1. 目前有四个Activity ,让Main4 在一个新的Task中,设置 Main4 taskAffinity 为 ‘.task2’,启动模式设置为 singleTask,这样我们从task3 启动task4 时自动会把Main4 放入新的task(.task2)中去了
图1

2. 若Main2Activity 不设置TaskAfinity, 启动模式为singleTask, Main4Activity启动Main2Activity 会复用Main2并把 main2 上面的 Main3 干掉。变成如下

图2

假如上不管设置不设置taskaffinity ,Main2Activity 启动模式为standard,直接会到当前task2中添加Main2 ,变成如下

在此情况下若需将main2 添加到默认的task,则需设置flag=FLAG_ACTIVITY_NEW_TASK 此时如下显示

我指定Main4的 Affinity为.task2,我们长按home 的时候会出现两个窗口分别对应不同的任务,我把task2 改成应用程序的包名,将只会出现一个窗口。但是,我们再去看task个数居然是1,也就是根本没有创建新的task ,因此默认affinity 为包名,只有改变了affinity 才会创建出一个新的task, 结论 要想创建task 一定要设置 taskAffinity属性并且和发起者的task名称不一致才行,代码中设置FLAG_ACTIVITY_NEW_TASK或者或者启动模式singleTask,

补充实验: task1的ActivityA start task2的activityB 如果task2中的activityB 之上有ActivityC ,singleTask 模式会把C 干掉(destroy),然后activityB调用newIntent 。

其他的flag 试试看

  1. Intent.FLAG_ACTIVITY_CLEAR_TOP
    跳转到的目标Activity 之后的activity 全部finish掉。但是只是其所在task的。
  2. 上面描述有不足,如果不想重新创建main2 可设置main2启动模式为singleTask, 会自动清除main2之上的act,并复用main2,并不一定非得设置singleTop
  3. 如果Main4只添加了FLAG_ACTIVITY_NEW_TASK ,它和设置main2为singeTask不一样,不会亲空默认栈中后面的act。如上图2所示
  4. Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    设置后在任务列表中不显示这个窗口,这和设置相同的taskAffinity 不显示原理不一样。
  5. FLAG_ACTIVITY_NO_ANIMATION
    不用系统界面跳转动画
  6. FLAG_ACTIVITY_REORDER_TO_FRONT
    a b c d 从d start b 并且带这个参数,b 不重新创建 task栈变为 a c d b 。但是从其他task中启动 b则无效

实验2 singleInstance

会另外启一个task,名字和 最原始task的名字一致(此时再任务列表中只会出现一个窗口,如果设置了taskAffinity 属性,就会和task一样出现两个窗口) ,再按home 点击app图标会回到启动app根(第一个)task的最后一个activity Main3。 Main4 这个activity 一直在自己的Task中,这个task只保留这一个activity 再次start 这个Activity的时候不再调用onCreate 而是 onNewIntent 方法。

singleTop

调用者调用之后,如果该 activity 在所在栈的栈顶,则不创建 ,如果不再栈顶,则在的task栈顶中新增一个activity。该值和FLAG_ACTIVITY_CLEAR_TOP 有相同作用,如果task2中启动singleTop的act,则会将改act添加到task2中,若task2的act 要让singleTop的在原来的栈中处理,则设置flag为FLAG_ACTIVITY_NEW_TASK

彻底弄清楚android 面试经典题:Handler 机制

向来觉得电话面试就觉得肯定黄,总有一种局促和不安,今天接到阿里的电话面,当时在家里。问的问题还是那几个老生常谈的问题。 view 的绘制啊, handler 机制啊,hashmap实现原理啊。效率啊,优化啊啥的。

今天可谓是都碰上了(其实还差那个asyntask 啊 http协议啊 多线程同步啊,jvm 啊,启动流程啊巴拉巴拉),这一关不过,下一关就没门啊,其实这个和项目经验或者一个人能不能做成事情并没有太大关系,最高的智商是把事做成,最高的情商是靠谱。

以前工作没那么多闲情看这个,那今天就带着面试的目的来彻底研究一下 面试第一题 Handler机制。

从应用开发这个角度来看,大家可能都知道 不能在子线程中直接new 一个hander。否则会抛出常见的

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

然后大家也知道(上面明显提示),在子线程中假如要创建handler 可以先Looper.prepare()然后就可以创建了。

我们写一个常见的用handler 进行线程间通讯例子,子线程发送消息给主线程更新UI
继续阅读“彻底弄清楚android 面试经典题:Handler 机制”

Mac下线刷Android 设备

今天淘到一个二手nexus6p,因为考虑到安全问题,我需要刷回原生Android,我从官方网站上下载了刷机包
下载地址:
https://developer.android.com/preview/download-712.html

注意,以下线刷方法会清空所有数据,请提前备份。
其次要下载platform-tools 才能使用adb命令,因为我装了Android Studio,
sdk中包含 SDK manager 所以不需要额外下载。
如果你不是开发者,建议只需要下载platform-tools 即可 下载地址:
https://developer.android.com/studio/releases/platform-tools.html#tos-header
选择相应版本下载。
解压,切换到platform-tools 目录下:

让设备切换到bootloader模式下:有两种方式,任选其一

  • 运行
adb reboot bootloader
  • 关机,按「电源键+音量下」开机

手机进入reboot 模式后,其中有一行小字 好像是 the device is locked 或者device is unlocked ,如果是 locked 则
运行

fastboot flashing unlock

否则略过进入下一步,在此过程中,手机会显示一个确认的操作,请留意。
等待解锁之后,在mac上解压下载的压缩包,命令行切换到解压后的目录中,运行

./flash-all

回车,等待刷机成功吧。成功之后会重启手机。进行一些手机初始化设置之后,开启开发者模式,连接上电脑,重新执行

adb reboot bootloader

进入reboot模式,运行

fastboot flashing lock

重新锁定,大功告成。
Let’s enjoy the new Android!

利用python 构建一个APP 模拟测试环境

背景

做app开发的,和后台连调是一个很重要的工作。在我来到这家公司之前,一只以为所有的功能是后台先开发出来然后app才开始开发。但是由于现在app开发和后台开发是两套人马,所以不可避免的需要同时开发甚至同时上线。我们不得不面临的一个问题是后台只给出了接口,客户端并没有可以连调的环境,这样就不得不自己写虚拟数据模拟。让客户端能够按某个流程能够点下去。

继续阅读“利用python 构建一个APP 模拟测试环境”