参考资料

AMS源码剖析(一)Activity生命周期处理

AMS源码剖析(二)onActivityResult实行进程

onActivityResult

onActivityResult机制的运用,归于Android基础知识,我想每一个Android程序员都用过,这里就不多做说明源码编程了,看一下运用办法

AActivity跳转BAcitivty并从BActivity回来数据

// AActivity
@Override
protected void onCreat源码年代e(@Nullable Bundle savedInstanceState) {
activityName = "AActivity";
super.approachonCreandroid的drawable类ate(savedInstanc程序员客栈eState);
setContentView(R.layout.activity_stack_test);
jumpBtn = findViewById(R.id.jumpBtn);
jumpB程序员薪酬一般多少tn.setOnClickListener(v -> {
BActivity.start(this, 1);
});
setActivityName();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("zyl", aapprovectivityName + "      requestCode = " + requestCode + "       resuAndroidltCode = " + resultCode);
super.onActivityResult(requestCode, resultCo源码de, data);
}
// BActivity
publapp装置下载ic static void start(Ac源码年代tivandroid体系ity act程序员客栈ivity, int requestCode) {
activity.startActivityForResult(new I源码编程ntent(activitAndroidy, BActivity.class), requestCode);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
activityName = "BActivity";
sandroid平板电脑价格uper.onCapplicationreate(savedInst程序员需求什么学历anceState);
setContentView(R.layout.activity_standroid体系ack_test);
}
@Override
public void finish() {
setResult(102);
supeapplicationr.fini源码之家sh();
}

当BActivity finish时,会将resultCode和requestCode经过AActivi源码编辑器ty的onActivityResult回传回来

Intent.FLAG_ACTIVITY_FORWARD_RESULT

这是onActivityResult的另一种表现形式,在日常开发中咱们经常会遇到如下场景
1.我要从Activity A 跳到B再跳到C
2.我要从Activity C 回来数据给Activity A
3.apple这种跳转层级有可能有很多层,比方 A ->B -> C -> D -> E等等

有同学看完必定会说,这个简略啊,每个Activity都完结onActivityResult,每次跳转都运用startActivityForResult不就行了,这样当然能够,可是代码会稍显冗余。实际上,Androiappointmentd体系现已帮咱们想好了这种场景的处理办法了

Int源码本钱ent.FLAG_ACTIVITY_FORWARD_RESULT的效果便是最后一个Activity直接调用第一个Activity的onActivityResult

示例:

以AActivity跳转BAct源码编辑器ivity跳转CActivity为例:

AActivity以startActivityFappleorResult办法翻开BActivity
    public static void start(Activity activity, int requestCode) {
Inte源码本钱nt intent = new Intent(acti源码本钱vity, BActivity.c源码本钱lass);
activity.startAct源码年代ivityForResult(intent, requeandroid体系stCode);
}
BActivity以一般办法翻开CActivity,设置Intentapp装置下载 的Flag Intentandroidstudio装置教程.FLAG_ACTIVITY_FORWARD_RESUL程序员一分钟毛遂自荐T
    public static void sappstoretart(Context context) {
Iappreciatentent intent = new Intent(contex程序员薪酬一般多少t, CActivapplicationity.cla源码编程ss);
intent.se源码之家tFlagsappearance(Intent.FLAG_ACTIVITY_FORWARD_applicationRESULT);
candroid是什么手机牌子ontext.startActivity(inten程序员计算器t);
}

Candroid是什么手机牌子Activity和BActivity回来后,AActivity会接approve收到从CActivity传递过来的音讯

源码解析

ActivityResult数据的写入

上篇程序员一分钟毛遂自荐文章咱们在解析Activity的finish进程时其实稍微触摸了一些onActivity的实行流程,在Activity的finish进程中,会调用到ActivityStack#finishActivit源码怎样做成app软件yResultsLocked办法

private void finishActappointmentivityResultsLocked(ActivityRecord r, intappear resultCode, Intent resultData) {
// zhangyulong 将效果传递给谁
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resul源码编辑器编程猫下载tTo
+ " who=" + r.resultWho + " req=" + r.requestCode
+ " res=" + resultCode + " data=" + resultData);
if (resultTo.userId != r.userId)android下载 {
if (resultData != null) {
resultDappleata.prepareT程序员怎样学oLeaveUser(r.userId);
}
}
if (r.info.applicationIn程序员需求什么学历fo.uid > 0) {
mService.grantUriPermissionFromIntentLocked(r.info.applandroid什么意思icationInfo.uid,
resultTo.packageName源码本钱, resultDat程序员是做什么的a,
resultTo.getUriPermissionsLoc程序员一分钟毛遂自荐ked(), resultTo.userId);
}
// zhangyulappleong 将ActivityResult效果放在resultTo中保存
resultTo.addResultLocked(r, r.resultWAndroidho, r.requestCode, resultCode,
resul程序员装逼代码tData);
r.resultTo = null;
}
else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
r.results = null;
r.pendingResults = null;
r.newIntents = null;
r.icicle = null;
}

入参意义:

  • r:行将finish的Activity
  • resultCode: 要传递的resultCode
  • resultData:要传递的Intent

这个办法将result信息封装成一个ResultIfo方针,并保存在列表中

ActivityResult数据的传递

在上篇文章中,咱们在剖析Activity的finish流程时提到过ActivityStack#resumeToappointmentpActivityInnerLocked办法,这个办法appreciate还有一个效果便是向上一个Activiandroidstudio装置教程ty,即源码resultTo传递ActivityResult

private boolea源码年代n resumeTopActivityInnerLocked(Activ程序员ityRecord prev, Activity程序员是做什么的Oapp装置下载ptions options) {
...
if (next.applicationapp != null && nexandroid下载装置t.app.thread != null) {
...
synchronized(mWindowManager.getWin源码年代dowManagerLock()) {
...
try {
// Deliver all pending results.
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = aandroid体系.size();
if (!next.finishing源码编辑器 && N > 0) {
if (DEandroidstudio装置教程BUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
next.app.thread.scheduleSendResult(next.appToken, a);
}
}
.apple..
}
}
...
} elseappear {
....
}
if (DEBUG_STACK) mStackSuappreciatepervisor.vali程序员dateTopActivitiesLocked();
return trueandroidstudio装置教程;
}

经过调用next.app.thread.scheduleSendResult(next.appToken, a)将ResultInfo发送到App进程中对应源码之家的Activity中源码年代,并回调onActivit源码yResult办法

Intent程序员计算器.FLAG_applicationACTIVITY_FORWARD_RESUappearanceLT的完结

上篇文章咱们剖析过,Activ程序员ity的建议流程会调用ActivityS程序员那么可爱tarter#sappearancetartActivity,这个办法有对Intent.FLAandroid手机G_ACTI源码编辑器手机版下载VITY_FORWARD_RESULT的处理,废话不多说,直接看源码:

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, Acti程序员培训班要多少钱vityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String c程序员是做什么的allingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOption程序员计算器s options, booleanandroid手机 ignoreTargetSecurity, boolean componentSpecified,
ActivityR程序员薪酬一般多少ecord[]android平板电脑价格 outActivity, TaskRecord inTask) {
...
ActappreciateivityRecord sourceRecord = null;
ActivityRecord resuandroid/yunosltRecoappointmentrd =程序员是做什么的 null;
if (resultTo != null程序员需求什么学历) {
// zhangyulon源码之家g 获取建议的源activity
sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
if (DEBU源码超市G_RESULTS) Slog.v(TAG_RESULTS,
"Will send result to " + resultTo + " " + sourceRecord);
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecorappreciated.finishing) {
resultRecor源码编程d = sou程序员客栈rceRecord;
}
}
}
if ((launch程序员客栈Flags & Intent.android/yunosFLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
// 增加Intent.FLAG_ACT程序员客栈IVITY_FORWARD_RESULT建议的源码年代Activity不能运用startActivityForResult建议
if (requestCode >=android体系 0) {
ActivityOptions.abort(options)程序员是做什么的;
return Act程序员需求什么学历ivityManager.START_FORWARD_程序员需求什么学历AND_REQUEST_CONFLICT;
}
// 将源Activity的randroid体系esultTo赋值给方针Activity
resultRecord = sourceRecord.resultTo;
if (resultRecord != null && !resultRecord.isInStackLocked()) {
resultRecord = null;
}
resultWho = sourceRecandroid下载ord.resultWho;
requestCode = sourceRecord.requestCo程序员培训班要多少钱de;
sourceRecord.resultTo = null;
if (r程序员薪酬一般多少esultR程序员怎样学ecord != null) {
resultRecord.remo程序员计算器veResultsLockeapproved(sourceRecord, resultWho, requestCode);
}
if (sourceRecord.launchedFromUid =appointment= callingUid) {
callingPackage程序员怎样学 = sourceRecord.lauappreciatenchedFromPackage;
}
}
...
returandroid手机n staandroid下载rtActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask源码编程, outActivity);
}

代码比较简略,首要android是什么手机牌子便是判别Inte程序员薪酬一般多少nt中是否带有Intent.FLAG_ACTIVITY_FORWARD_RESULT标签,如果有,则将源Activity的resultTo赋值给Android方针Activity

如果有多个中心Activity,比方运用approve这种办法建议ABCDE五个Activity,其间,BCD都是中心Activity,
那么resultTo的传递进程如下源码编辑器编程猫下载
1.app装置下载A建议B,A作为resultTo传递给B
2.B建议C,增加Intent.FLAG_ACTIVITY_FORWARD_RE源码年代SULT,C获取B的ResultTo源码即A
3.C建议程序员需求什么学历D,增加Intent.FLAG_ACTIVITY_FORWARD_RESULT,D获取C的ResultTo即A
4.D建议E,添程序员客栈加Intent.FLAG_ACTIVITY_FORWARD_RESULTandroid下载,E获取D的ResultTo即A
5.从E逐级回来,当E回来时,将ResultInfo赋值给A,当回来到A时,触发next.app.thread.scheduleSendResult(next.appToken, a)