使用如下代码:
本来是想实现tvMyAccount这个TextView的宽度始终等于高度。
但是这个会造成UI线程一直在处于忙碌状态,可能会造成如下后果:
1. Android Studio中Layout Inspector无法获取Activity的部局
2. 使用Instrumentation进行自动化测试时,无法测试
addOnGlobalLayoutListener的原理
待整理
使用如下代码:
本来是想实现tvMyAccount这个TextView的宽度始终等于高度。
但是这个会造成UI线程一直在处于忙碌状态,可能会造成如下后果:
1. Android Studio中Layout Inspector无法获取Activity的部局
2. 使用Instrumentation进行自动化测试时,无法测试
待整理
没在代码中看出原因,在greenDao的源代码中只是硬性的规定必须使用Long/long型,估计是为了确保自增值的范围足够大?(应该不是)
做此限制的代码在文件DaoGenerator/src/org/greenrobot/greendao/generator/Property.java中
在sqlite库的源码中,绑定字段的地方也没有int型相关的参数,只有bindLong和bindDouble、bindString等,和这个有关?
sqlite库源码:frameworks\base\core\java\android\database\sqlite\SQLiteProgram.java
奇怪的是,官方代码中的意思是Long/long都可以,但long是不行的,在插入2条记录的时候就会报ndroid.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: notes.localid错误。
这个涉及使用sql语句向数据库的自增字段插入数据的问题,sql语句如下:
insert into table(id, name) values(NULL, ‘ldr’);
在greenDao中如果成员是long型,则未赋值时返回的是0,如果是Long型,则返回的是null,所以是这个原因?
这个涉及的文件是bean类生成的相应的Dao类,比如”NoteBeanDao.java”
本文基于Android8.1系统进行测试
1. standard
默认方式,每次总是新建一个Activity,并放在当前任务的顶端。
2. singleTop(和FLAG_ACTIVITY_SINGLE_TOP标志一样的作用)
如果当前Activity栈的顶部是要打开的Activity,则不新建Activity,而是复用这个Activity,但是intent是通过onNewIntent事件传入(不能通过getIntent得到)。
如果当前Activity栈的顶部不是要打开的Activity,则新建一个Activity
3. singleTask
若被启动的activity的taskAffinity与调起这个activity的不同,则为此Activity新建一个任务,并且此Activity为新建任务的根Activity。若相同,则与普通启动无区别。
若所有task中已经有此Activity,则不新建此Activity,将Activity所在的task调到前台,并清楚Activity到栈顶之间的Activity。
三种情况:
1) Activity存在于某个任务中,且在栈顶,不创建新Activity,已存在的Activity触发onNewIntent
2)Activity存在于某个任务中,但不在栈顶,不创建新Activity。
又分两种情况:
I. 如果栈顶Activity的taskAffinity与此Activity的相同则自动关闭栈顶的Activity,直到此Activity时,触发onNewIntent
II. 如果栈顶Activity的taskAffinity与此Activity的不同,并且也是singleTask的,不会自动关闭顶部 的Activity,需要手动关闭,直到此Activity时,触发onNewIntent(但是在某些机型上没发现这种情况,而是I中的情况)(目前测试在Android9.0之前是这样的,9.0之后是第I种情况)
3)Activity不存在于某个任务中,则在当前任务中新建一个Activity并放在栈顶
4. singleInstance
该Activity始终在一个新的任务中创建,并且由该Activity启动的其他Activity始终在另外的任务中。就是说该Activity所在的任务有且只有一个Activity。
1. moveTaskToBack()函数
五、其他参考链接
用于根据intent获取AndroidManifest.xml中的Activity或者Service或者Provider中包含对应的intent-filter的信息?
成员包括ActivityInfo、ServieInfo、ProviderInfo、Icon等。
从AndroidManifest.xml中获取的应用的activity或者receiver的信息。
ActivityStack主管,在ActivityManagerService中使用一个ActivityStackSupervisor来管理所有的ActivityStack?
通过查找系统所有代码发现,只有在此类的createStack函数中新建了ActivityStack实例(并不是说只创建了一个实例),所以所有的ActivityStack是通过这个对象来管理的。
也只有在ActivityManagerService中新建了一个ActivityStackSuperVisor实例,也就是系统中只有一个ActivityStackSupervisor对象
另外这个类还负责和PackmanagerService的一些交互,还用于判断进程是否存在(调用ams的函数),并起动新进程(调用ams的函数)
用于表示Activity的一结构,包括Activity相关的很多信息。
一些变量
final String taskAffinity – 在AndroidManifest.xml中的Activity节点中定义的taskAffinity
此Activity是不是一个ResolverActivity
static final int APPLICATION_ACTIVITY_TYPE = 0;
static final int HOME_ACTIVITY_TYPE = 1;
static final int RECENTS_ACTIVITY_TYPE = 2;
static final int ASSISTANT_ACTIVITY_TYPE = 3;
诠释如何启动Activity的控制器。
根据intent和flag信息,并将这些信息准备相应的activity、Activity Task和Activity Stack的信息。
我看了一下代码,主要是根据intent中的flag信息处理相关的Activity、Activity Task和Activity Stack的相关信息。
这个类是为了减轻ActivityManagerService的代码量,分离出来一部分逻辑,好让逻辑更清晰一些。
mSourceRecord – 源Activity的ActivityRecord对象
mInTask – 调用startActivity的context所在的task,可能为null(比如service中调用或者通知栏调用?),在启动Activity时在setInitialState函数中传入被赋值
mLaunchFlags – 新Activity启动时的一些FLAG标志,通过一系列的计算得到
private boolean mLaunchSingleTop; 在setInitialState函数中根据要启动的Activity的ActivityRecord对象的launchMode判断
private boolean mLaunchSingleInstance; 在setInitialState函数中根据要启动的Activity的ActivityRecord对象的launchMode判断
private boolean mLaunchSingleTask; 在setInitialState函数中根据要启动的Activity的ActivityRecord对象的launchMode判断
在startActivityUnchecked函数中调用,用于初始化本类中的一些变量。
计算要启动的Activity的task标志
计算源Activity所在的stack?
Activity栈类,用于管理某个Activity栈。
其中:
final ArrayList<ActivityRecord> mLRUActivities – 是用于存储正在运行Activity列表,列表中最外面一条记录,是最近使用的Activity
final ArrayList<ActivityRecord> mActivities – 此Task中的Activity列表
private ActivityStack mStack; – 此Task所在的Activity栈
获取任务中根Activity的 intent
从根Activity往外遍历(列表mActivities),获取非finishing状态的Activity的ActivityRecord对象
继承自Activity,如果startActivity传入的intent对应多个应用,比如intent中打开url链接,但是系统中有多个浏览器应用,将弹出这个Activity让用户选择 。
Art是在Android4.4系统中加入的,但是默认是不开启的
Art和Dalvik的切换是通过指定一个系统设置项来切换的,见art/Android.mk中.PHONY: use-art下面那一段脚本
本文摘录片段
libdvm.so是DalvikVm的so库
libart.so是Art Vm的so库
之所以两个能同时切换,是因为他们都实现了JNI_Create_JavaVm的入口函数。
在Android4.4加入Art之后,一直是默认没有开启的,直到Android5.0,DalvikVm彻底被删除,art担当大任
可以对比下4.4和5.0源码中dalvik/vm下的代码结构
http://androidxref.com/4.4_r1/xref/dalvik/vm/
http://androidxref.com/5.0.0_r2/xref/dalvik/vm/
可以看到从5.0开始,dalvik的代码已经被删除掉了
本文基于Android8.1系统进行研究
在Linux内核启动完成后,首先启动系统的第一个进程init进程
init进程会读取init.rc中的配置文件
其中有Zygote的配置,init进程将启动zygote进程
zygote的入口在app_main.cpp中的main函数中
在app_main.cpp中的main函数中,首先解析传入的相关参数,并通过如下代码进入ZygoteInit的main函数中
runtime是AppRuntime的一个实例,AppRuntim继承自AndroidRuntime
start函数定义在AndroidRuntime中,下面是start函数的注释
start函数中的这段代码切入到了startVm函数中
这个函数前边也是一堆处理Vm启动参数的逻辑
在函数的最好调用JNI_CreateJavaVM函数通过c++层的库创建虚拟机
JNI_CreateJavaVM函数是在art/runtime/java_vm_ext.cc中实现的,代码如下:
Runtime是在art/runtime/runtime.h中定义的类
Runtime::Current()返回一个静态的Runtime实例,代码如下:
runtime-Start()启动虚拟机
Android ART运行时无缝替换Dalvik虚拟机的过程分析
https://blog.csdn.net/zhu929033262/article/details/77053640
Android虚拟机art流程:从zygote开始梳理art的启动(1)
代码如下:
其中,ajax前面这段代码是用来附加token的
$.ajaxSetup({ headers: { ‘X-CSRF-TOKEN’ : ‘{{ csrf_token() }}’ } });
基于Android8.1系统源码中的注释翻译
翻译如下:
在一个Activity被杀死之前被调用以取出Activity中每个对象实例的状态,这些状态可以在onCreate或者onRestoreInstanceState方法中被重新加载到实例(此方法产生的Bundle将传递到那两个方法)。
这个方法在一个Activity可能被杀掉之前(不是刚刚被杀之前)被调用,以便于之后某些时候Activity被重新打开时可以恢复它的(某些变量的)状态。比如,如果ActivityB被打开并显示在ActivityA之前(ActivityA被置于后台),在某些时候ActivityA由于系统资源回收被杀掉,AvtivityA将有机会使用此方法来保存用户界面的当前状态,以便当用户回到ActivityA时,用户界面的状态可以在Activity的onCreate或者onRestoreInstanceState中被恢复。
不要把这个方法和Activity的生命周期比如onPause和onStop混淆。比如,当从ActivityB退出返回到ActivityA时,onPause和onStop将被调用,但是onSaveInstanceState不会被调用,此时没有必要对ActivityB调用此方法,因为ActivityB将被销毁,并且不会被恢复。另外一个例子,当ActivityB被打开并显示在ActivityA之前时,系统可能会避免调用ActivityA的onSaveInstanceState方法,因为在ActivityB的生命周期内,ActivityA的ui状态可能一直保持完整。
大部分UI组件的实例的(状态保存)默认实现是通过对布局中有id属性的view调用view自身的onSaveInstanceState()方法,通过id保存当前有焦点的view(通过view的onRestoreInstanceState来恢复状态)。如果你想使用这个方法来保存某个view的状态,最好使用view自身的onSaveInstanceState来处理,否则每个(Activity中)的view实例都需要你写代码来维护。
如果此方法被调用,将在onStop之前发生,但是不能保证肯定是在onPause之后发生。
原文如下:
本文 基于Android8.1系统