Mac系统Charles破解版

Mac系统Charles破解版

1,环境:

mac ---10.12.6 

charles---4.2最新的版本都可以

2,安装:

官方地址:https://www.charlesproxy.com

3,破解:

可以参考CSDN博客上面的破解教程,比如修改charles.jar文件或者替换掉原来的软件。

我的方法是—注册码!!!

按照常规安装好charles软件之后,打开软件,点击工具栏中的help –> register

输入如下信息:

Registered Name: https://zhile.io
License Key: 48891cf209c6d32bf4

Mac环境下,出现brew command not found错误的解决方法
git常用命令

git常用命令

一、常用命令

切换到master分支:git checkout master

查看已有本地及远程分支:git branch -a(先git pull拉下全部数据)

查看远程分支:git branch -r

查看所有分支:git branch -a

查看本地分支:git branch

删除远程dev分支:git push origin –delete dev

删除本地dev分支:git branch -d dev

从远程的origin仓库的master分支下载到本地,并新建一个test分支:git fetch origin master:test

本地从当前所在分支上创建一个新分支: git checkout -b 新分支名

查看test分支与本地原有分支的不同:git diff test

将test分支和当前分支合并:git merge test

将远程git仓库里的指定分支拉取到本地(本地不存在的分支):git checkout -b 本地分支 origin/远程分支,或者 git pull origin dev(remote):dev(local)

将本地master分支提交到远程dev分支:git push origin master:dev

Anroid开发艺术探究

Anroid开发艺术探究

1.onStart 和 onResume、onPause和onStop从描述上来看差不多,对我们来说有什么实质的不同?
onStart 和 onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的,除了这种区别,没有其他区别

2.假设当前Activity为A,如果这时用户打开一个新Activity B,那么 B 的onResume()和 A 的onPaus()哪个先执行呢?
启动Activity的请求会由Instrumentation来处理,然后它通过Binder向AMS发请求,AMS内部维护着一个ActivityStack并负责栈内的Activvity的状态,AMS通过
ActivityThread去同步Activity的状态从而完成生命周期方法的调用。在ActivityStack中的resumeTopActivityInnerLocked方法中,在新Acctivity启动之前,
栈顶的Activity需要先onPause()后,新Activity才能启动。最终在ActivityStackSupervisor中的realStartActivityLocked方法会调用scheduleLaunchActivity,
接着完成新Activity的onCreate、onStart、onResume的调用过程。因此,可以得到结论,是旧Activity先onPause,然后新Activity再启动。

3.Activity被销毁并重建后,我们去获取之前的存储字符串,接受的位置可以是onRestoreInstanceState 或者 onCreate 方法,两者区别是?
onRestoreInstanceState一旦被调用,其参数Bundle savedInstanceState 一定是有值的,我们不用额外的拍断是否为空;
但是onCreate不行,onCreate如果正常启动的话,其参数Bundle savedInstanceState为null, 所以必须要额外判断。

4.onSaveInstanceState和onRestoreInstanceState,在正常流程下会出发么?
系统只在Activity异常种植的时候才会调用onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,其他情况不会出发这个过程。

5.比如目前任务栈S1中的情况为ABC,这个时候Activity D 以singleTask模式请求启动,其所需要的任务栈为 S2,由于S2和D的实例均不存在,所以系统会先创建
任务栈S2,然后在创建D的实例并将其入栈到S2.

6.TaskAffinity任务相关性。
这个参数标识一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。可以为每个Activity都单独制定TaskAffinity属性,
这个属性必须不能和包名相同,否则就相当于没有制定。TaskAffinity属性主要和singleTask启动模式或者allTaskReparenting属性配对使用。当TaskAffinity和singleTask启动模式配对使用的时候,它是具有该模式的Activity的目前任务栈的名字,待启动的Activity回运行在名字和TaskAffinity相同的任务栈中。
当TaskAffinity和allowTaskReparenting结合的时候,会产生特殊的效果。当一个应用A启动了应用B的某个Activity后,如果这个Activity的allTaskReparenting属性为true的话,那么当应用B被启动后,词Activity回直接从应用A的任务栈转移到应用B的任务栈中。

7.SharedPerences是否安全?
SharedPreferences不支持两个进程同时去执行写操作,否则会导致一定几率的数据丢失,因为SharedPreferences底层是通过读/写XML文件来实现的,并发会出问题。
每个应用的SharedPreferences文件都在当前包所在的data目录下查看到,目录位于 /data/data/pacakage name/shared_prefs目录下。
SharedPreferences也属于文件的一种,但是由于系统对他的读/写有一定的缓存策略,即在内存中有一份ShareePreferences文件的缓存,因此在多进程下,系统对它的读写诗不可靠的,当面对高并发的读/写访问,有很大几率丢失文件。

8.Serializable接口的原理及serialVersionUID作用?
想让一个对象实现序列化,只需要这个类实现Serializable接口并声明一个serialVersionUID即可。实际上,甚至连这个serialVersionUID也不是必须的。如何进行对象的序列化和反序列化也很简单,只需要采用ObjectOutputStream和ObjectInputStream,readObject()writeObject()函数。
serialVersionUID是用来辅助序列化和反序列化过程的,原则上序列化后的数据中的serialVersionUID只有和当前累的serialVersionUID相同时才能够正常的被反序列化。
serialVersionUID的详细工作机制时这样的:序列化的时候系统把当前类的serialVersionUID写入序列化文件中,当反序列化时候系统回去检测文件中的serialVersionUID,看它是否和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本时相同的,这个时候可以成功反序列化;否则就说明当前类和序列化的类相比发生了某些变化,比如成员变量的数量、类型可能发生了改变,这个时候时无法正常反序列化的。

9.Parcelable接口原理?
Parcelable也是一个接口,只要实现这个接口,一个类的对象就可以实现序列化并通过Intent和Binder传递。
Parcel内部包装了可序列化的数据,可以在Binder中自由传输。
序列化的功能由writeToParcel方法来完成,最终时通过Parcel的一系列write方法来完成的;
反序列化功能由CREATOR来完成,其内部表明了如何创建序列化对象和数组,并通过Parcel的一系列read方法来完成反序列化过程。

应用程序返回按键执行流程

应用程序返回按键执行流程

从这篇文章中我们开始分析android系统的事件分发流程,其实网上已经有了很多关于android系统的事件分发流程的文章,奈何看了很多但是印象还不是很深,所以这里总结一番。
android系统的事件分发流程分为很多部分:

  • Native层 –> ViewRootImpl层 –> DecorView层 –> Activity层 –> ViewGroup层 –> View层

所以android系统的事件分发流程是从Native层开始的,然后分发到ViewRootImpl中,然后分发到DecorView层,然后分发到ViewGroup层,最后分发到View层中。下面我们将从Native层开始分析事件的分发流程。

在Native层android系统的事件流程:

  • Android系统是从从底层驱动中获取各种原始的用户消息,包括按键、触摸屏、鼠标、滚迹球等用户事件消息。

  • 在获取用户消息之后,android系统会对最原始的消息进行预处理,包括两个方面:一方面,将消息转化成系统可以处理的消息事件;另一方面,处理一些特殊的事件,比如HOME、MENU、POWER键等处理(前面的几篇文章中我们已经分析了系统按键处理逻辑的执行流程)。

  • 将处理后的消息事件分发到各个应用进程,这个需要使用IPC机制,Android系统使用管道来进行消息的传递。

  • Android系统使用InputManager类来管理消息,而具体的功能则是通过InputReaderThread和InputDispatcherThread两个线程来实现。其中InputReaderThread线程负责消息的读取,而InputDispatcherThread则负责消息的预处理和分发到各个应用进程中。

  • Acitivty系统在SystemServer进程中启动WindowManagerService服务,然后在WindowManagerService服务中启动InputManagerService服务。

可以看到在Native层,主要创建了两个两个线程,其中一个用于读取消息,另一个用于分发消息,消息经过分发最终会上传至App中。

在ViewRootImpl层android系统的事件流程

在Native层的事件分发线程中,经过事件的分发流程,最终会调用InputEventSender的dispatchInputEventFinished方法,可以看一下具体代码的实现:

1
2
3
private void dispatchInputEventFinished(int seq, boolean handled) {
onInputEventFinished(seq, handled);
}

在dispatchInputEventFinished方法中我们最终调用的是onInputEventFinished方法,然后我们查看onInputEventFinished方法的实现,发现其是一个空方法。。。,好吧,经过分析我们发现,Native层最终调用的并不是InputEventSender,而是调用InputEventSender的子类ImeInputEventSender,即ImeInputEventSender的onInputEventFinished方法,该类定义在源文件InputMethodManager中:

电源开关机按键事件流程

电源开关机按键事件流程

前面我们讲解了系统截屏按键处理流程,HOME按键处理流程,今天再来讲解一下电源开关机按键事件流程,当然这也是系统按键处理流程方面的最后一篇博客了。

和截屏按键、HOME按键的处理流程类似,电源按键由于也是系统级别的按键,所以对其的事件处理逻辑是和截屏按键、HOME按键类似,不在某一个App中,而是在PhoneWindowManager的dispatchUnhandledKey方法中。所以和前面两篇类似,这里我们也是从PhoneWindowManager的dispatchUnhandledKey方法开始我们今天电源开关机按键的事件流程分析。

下面首先看一下dispatchUnhandledKey方法的实现逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
...
KeyEvent fallbackEvent = null;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
final int keyCode = event.getKeyCode();
final int metaState = event.getMetaState();
final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0;

// Check for fallback actions specified by the key character map.
final FallbackAction fallbackAction;
if (initialDown) {
fallbackAction = kcm.getFallbackAction(keyCode, metaState);
} else {
fallbackAction = mFallbackActions.get(keyCode);
}

if (fallbackAction != null) {
if (DEBUG_INPUT) {
Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode
+ " metaState=" + Integer.toHexString(fallbackAction.metaState));
}

final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
fallbackEvent = KeyEvent.obtain(
event.getDownTime(), event.getEventTime(),
event.getAction(), fallbackAction.keyCode,
event.getRepeatCount(), fallbackAction.metaState,
event.getDeviceId(), event.getScanCode(),
flags, event.getSource(), null);

if (!interceptFallback(win, fallbackEvent, policyFlags)) {
fallbackEvent.recycle();
fallbackEvent = null;
}

if (initialDown) {
mFallbackActions.put(keyCode, fallbackAction);
} else if (event.getAction() == KeyEvent.ACTION_UP) {
mFallbackActions.remove(keyCode);
fallbackAction.recycle();
}
}
}
...
return fallbackEvent;
}

通过前面两篇文章的分析
android源码解析(二十六)–>截屏事件流程  
android源码解析(二十七)–>HOME事件流程
我们知道关于系统按键的处理逻辑被下放到了interceptFallback方法中,所以我们继续看一下interceptFallback方法的实现逻辑。

HOME事件流程

HOME事件流程

上一篇文章中我们介绍了android系统的截屏事件,由于截屏事件是一种系统全局处理事件,所以事件的处理逻辑不是在App中执行,而是在PhoneWindowManager中执行。而本文我们现在主要讲解android系统中HOME按键的事件处理,和截屏事件类似,这里的HOME按键也是系统级别的按键事件监听,所以其处理事件的逻辑也应该和截屏事件处理流程类似,从上一篇文章的分析过冲中我们不难发现,系统级别的按键处理逻辑其实都是在PhoneWindowManager中,所以HOME按键的处理逻辑也是在PhoneWindowManager的dispatchUnhandledKey方法中执行,那么我们就从dispatchUnhandleKey方法开始分析HOME按键的处理流程。

好吧我们看一下PhoneWindowManager的dispatchUnhandleKey方法的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@Override
public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
...
KeyEvent fallbackEvent = null;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
final int keyCode = event.getKeyCode();
final int metaState = event.getMetaState();
final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0;

// Check for fallback actions specified by the key character map.
final FallbackAction fallbackAction;
if (initialDown) {
fallbackAction = kcm.getFallbackAction(keyCode, metaState);
} else {
fallbackAction = mFallbackActions.get(keyCode);
}

if (fallbackAction != null) {
if (DEBUG_INPUT) {
Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode
+ " metaState=" + Integer.toHexString(fallbackAction.metaState));
}

final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
fallbackEvent = KeyEvent.obtain(
event.getDownTime(), event.getEventTime(),
event.getAction(), fallbackAction.keyCode,
event.getRepeatCount(), fallbackAction.metaState,
event.getDeviceId(), event.getScanCode(),
flags, event.getSource(), null);

if (!interceptFallback(win, fallbackEvent, policyFlags)) {
fallbackEvent.recycle();
fallbackEvent = null;
}

if (initialDown) {
mFallbackActions.put(keyCode, fallbackAction);
} else if (event.getAction() == KeyEvent.ACTION_UP) {
mFallbackActions.remove(keyCode);
fallbackAction.recycle();
}
}
}

if (DEBUG_INPUT) {
if (fallbackEvent == null) {
Slog.d(TAG, "No fallback.");
} else {
Slog.d(TAG, "Performing fallback: " + fallbackEvent);
}
}
return fallbackEvent;
}

通过查看源码,我们重点看一下dispatchUnhandledKey方法中调用的interceptFallback方法,关于HOME按键的处理逻辑也是在这个方法体中的,所以继续看一下interceptFallback方法的实现:

截屏事件流程

截屏事件流程

今天这篇文章我们主要讲一下Android系统中的截屏事件处理流程。用过android系统手机的同学应该都知道,一般的android手机按下音量减少键和电源按键就会触发截屏事件(国内定制机做个修改的这里就不做考虑了)。那么这里的截屏事件是如何触发的呢?触发之后android系统是如何实现截屏操作的呢?带着这两个问题,开始我们的源码阅读流程。

我们知道这里的截屏事件是通过我们的按键操作触发的,所以这里就需要我们从android系统的按键触发模块开始看起,由于我们在不同的App页面,操作音量减少键和电源键都会触发系统的截屏处理,所以这里的按键触发逻辑应该是Android系统的全局按键处理逻辑。

在android系统中,由于我们的每一个Android界面都是一个Activity,而界面的显示都是通过Window对象实现的,每个Window对象实际上都是PhoneWindow的实例,而每个PhoneWindow对象都一个PhoneWindowManager对象,当我们在Activity界面执行按键操作的时候,在将按键的处理操作分发到App之前,首先会回调PhoneWindowManager中的dispatchUnhandledKey方法,该方法主要用于执行当前App处理按键之前的操作,我们具体看一下该方法的实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/** {@inheritDoc} */
@Override
public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
...
KeyEvent fallbackEvent = null;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
final int keyCode = event.getKeyCode();
final int metaState = event.getMetaState();
final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0;

// Check for fallback actions specified by the key character map.
final FallbackAction fallbackAction;
if (initialDown) {
fallbackAction = kcm.getFallbackAction(keyCode, metaState);
} else {
fallbackAction = mFallbackActions.get(keyCode);
}

if (fallbackAction != null) {
...
final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
fallbackEvent = KeyEvent.obtain(
event.getDownTime(), event.getEventTime(),
event.getAction(), fallbackAction.keyCode,
event.getRepeatCount(), fallbackAction.metaState,
event.getDeviceId(), event.getScanCode(),
flags, event.getSource(), null);

if (!interceptFallback(win, fallbackEvent, policyFlags)) {
fallbackEvent.recycle();
fallbackEvent = null;
}

if (initialDown) {
mFallbackActions.put(keyCode, fallbackAction);
} else if (event.getAction() == KeyEvent.ACTION_UP) {
mFallbackActions.remove(keyCode);
fallbackAction.recycle();
}
}
}

...
return fallbackEvent;
}

这里我们关注一下方法体中调用的:interceptFallback方法,通过调用该方法将处理按键的操作下发到该方法中,我们继续看一下该方法的实现逻辑。

onLowMemory执行流程

onLowMemory执行流程

上篇文章中我们分析了Activity的onSaveInstanceState方法执行时机,知道了Activity在一般情况下,若只是执行onPause方法则不会执行onSaveInstanceState方法,而一旦执行了onStop方法就会执行onSaveInstanceState方法,具体的信息,可以参见onSaveInstanceState方法执行时机:android源码解析(二十四)–>onSaveInstanceState执行时机 这篇文章中同样的我们分析一下Actvity(当然不只是Activity,同样包含Servier,ContentProvider,Application等)的另一个内部方法:onLowMemory。该方法主要用于当前系统可用内存比较低的时候回调使用。

这里简单介绍一下Android系统的内存分配机制。Android系统中一个个的App都是一个个不同的应用进程,拥有各自的JVM与运行时,每个App的进程可使用的内存大小都是固定的,当系统中App打开数量过多时,就会使Android系统的可用内存降低,对于当前正在使用的App而言,可能还需要继续申请系统内存,而我们的剩余系统内存已经不足以被当前App所申请了,这时候系统会自动的清理那些后台进程,进而释放出可用内存用于前台进程的使用,当然这里系统清理后台进程的算法不是我们讨论的重点。这里我们只是大概的分析Android系统回调Activity的onLowMemory方法的流程。

通过前面关于Activity的启动流程分析我们知道ActivityManagerService是整个Android系统的管理中枢,负责Activity,Servier等四大组件的启动与销毁等工作,同样的对于应用进程的管理工作也是在ActivityMaangerServier中完成的,我们知道android系统中有两个比较重要的进程Zygote进程和SystemServer进程,其中Zygote进程是整个Android系统的根进程,其他所有的进程都是通过Zygote进程fork出来的。而SystemServer进程则用于运行各种服务,为其他的应用进程提供各种功能接口等,在前面我们分析过SystemServer进程的启动流程(参考: android源码解析之(九)–>SystemServer进程启动流程)其中在SystemServer的startBootService方法中我们调用了:

1
2
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();

方法,看其注释说明,说的是为System进程初始化Application实例,这里我们可以看一下该方法的具体实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));

ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}

这里简单介绍一下ServierManager是一个管理服务的服务,而其addServier方法就是注册各种服务(服务注册到JNI层,具体的关于是如何注册到JNI层的这里暂不做过多的解释)。可以发现在方法体中我们注册了名称为:memInfo的服务MemBinder,MemBinder是一个Binder类型的服务,主要用于检测系统内存情况,这里可以看一下其具体的实现逻辑:

onSaveInstanceState执行时机

onSaveInstanceState执行时机

我们已经分析过Activity的启动流程,从中也分析了Activity的生命周期。而其中有一个生命周期方法:onSaveInstanceState方法,今天我们主要讲解一下onSaveInstanceState方法的执行时机。
可能部分同学对Activity的onSaveInstanceState方法不是特别熟悉,这里我们简单介绍一下。onSaveInstanceState方法是Activity的成员方法,主要用于在Activity销毁时保存Activity相关的对象信息,而其执行的时机不是我们主动调用的,而是Android系统的framework帮忙调用的,而其调用的时机,可以参考android系统的介绍:

This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via {@link #onCreate} or {@link #onRestoreInstanceState}.

可以发现onSaveInstanceState方法会在Activity将要被kill的时候执行。O(∩_∩)O哈哈~,可能跟以前讲解的内容不是太对,我们看过不少文章都是说onSaveInstanceStatex方法会在Activity容易被销毁的时候执行。那么这里明明说的是当Activity被销毁的时候就会执行onSaveInstanceState方法,那么具体的情况是如何的呢?我们具体看一下源码吧,哈哈。

通过分析Activity的生命周期方法,我们知道onSaveInstanceState方法在onPause方法之后执行在onStop方法之前执行。这里我们首先看一下onPause方法的源码逻辑。

Activity在执行onPause方法的时候回回调ActivityThread的handlePauseActivity方法,不太熟悉的同学可以参考: android源码解析之(十四)–>Activity启动流程,文章中有对Activity生命周期的详细讲解。

好吧,先具体看一下ActivityThread.handlePauseActivity的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
if (userLeaving) {
performUserLeavingActivity(r);
}

r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb());

// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}

// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
}
}
mSomeActivitiesChanged = true;
}
}

在方法体中我们除了执行一些其他的操作,然后在handlePauseActivity方法体中调用了performPauseActivity方法,这个方法就是具体执行回调pauseActivity操作的方法,既然这样我们在看一下performPauseActivity方法的实现:

1
2
3
4
5
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState) : null;
}

可以发现在performPauseActivity方法中首先判断ActivityClientRecord是否为空,然后又调用了performPauseActivity方法的重载方法:


:D 一言句子获取中...