当前位置: 首页 > news >正文

网站做nat映射需要哪些端口社群营销的方法和技巧

网站做nat映射需要哪些端口,社群营销的方法和技巧,网站丢失怎么解决,上海高端网站制作公司Android 7.0引入了新特性:Direct Boot Mode,设备启动后进入的一个新模式,直到用户解锁(unlock)设备此阶段结束。在这个模式下,系统调用 resolveHomeActivity 找到的是FallbackHome ,而不是我们的…

Android 7.0引入了新特性:Direct Boot Mode,设备启动后进入的一个新模式,直到用户解锁(unlock)设备此阶段结束。在这个模式下,系统调用 resolveHomeActivity 找到的是FallbackHome ,而不是我们的桌面应用。所以系统开始启动的是 FallbackHome 这个"桌面"。

03-13 16:58:41.359   431   431 D test10  : ===getDefaultTaskDisplayArea===
03-13 16:58:41.359   431   431 D test10  : comp:null
ResolveInfo:ResolveInfo{b15783 com.android.settings/.FallbackHome p=-1000 m=0x108000}
03-13 16:58:41.361   431   431 D test10  : bestChoice:ResolveInfo{b15783 com.android.settings/.FallbackHome p=-1000 m=0x108000}
03-13 16:58:41.361   431   431 D test10  : aInfo:ActivityInfo{67e5d00 com.android.settings.FallbackHome}

那为什么找到是FallbackHome 呢?FallbackHome 位于 com.android.settings这个包下,看一下主配置文件

//packages\apps\Settings\AndroidManifest.xml<activity android:name=".FallbackHome"//......<intent-filter android:priority="-1000"><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity><application android:label="@string/settings_label"//......android:directBootAware="true"android:name=".SettingsApplication"android:appComponentFactory="androidx.core.app.CoreComponentFactory">

FallbackHome设置了HOME属性,且settings application配置了directBootAware属性,所以找到的是FallbackHome

FallbackHome的启动

FallbackHome的启动主要分为两个阶段

  1. systemserver告知Zygote要创建新进程
  2. 新进程通知AMS启动FallbackHome

systemserver告知Zygote要创建新进程

systemserver之间的调用这里就不详细分析,可以看一下调用的堆栈

startSpecificActivity r:ActivityRecord{eebff5 u0 com.android.settings/.FallbackHome t2}
03-13 16:58:41.400   431   431 D test10  : java.lang.Exception
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStackSupervisor.startSpecificActivity(ActivityStackSupervisor.java:979)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:1970)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:1516)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.RootWindowContainer.resumeFocusedStacksTopActivities(RootWindowContainer.java:2311)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1736)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1525)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1189)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:670)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityStartController.startHomeActivity(ActivityStartController.java:207)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.RootWindowContainer.startHomeOnTaskDisplayArea(RootWindowContainer.java:1549)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1491)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1475)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.RootWindowContainer.startHomeOnAllDisplays(RootWindowContainer.java:1456)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.wm.ActivityTaskManagerService$LocalService.startHomeOnAllDisplays(ActivityTaskManagerService.java:6727)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:9689)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.SystemServer.startOtherServices(SystemServer.java:2257)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.SystemServer.run(SystemServer.java:599)
03-13 16:58:41.400   431   431 D test10  :      at com.android.server.SystemServer.main(SystemServer.java:415)
03-13 16:58:41.400   431   431 D test10  :      at java.lang.reflect.Method.invoke(Native Method)
03-13 16:58:41.400   431   431 D test10  :      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
03-13 16:58:41.400   431   431 D test10  :      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:925)

可以看出,首先在ActivityManagerService的systemReady方法中调用,一直执行到ActivityStackSupervisor的startSpecificActivity方法

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {//......final boolean isTop = andResume && r.isTopRunningActivity();mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");}

通过 startProcessAsync请求 Zygote创建 FallbackHome进程。startProcessAsync经过一步步的调用,最后调用到ProcessList的start方法

//frameworks\base\services\core\java\com\android\server\am\ProcessList.java
@GuardedBy("mService")boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,boolean mountExtStorageFull, String abiOverride) {//......// Start the process.  It will either succeed and return a result containing// the PID of the new process, or else throw a RuntimeException.final String entryPoint = "android.app.ActivityThread";return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,instructionSet, invokeWith, startTime);}

注意这里的一个参数entryPoint为 “android.app.ActivityThread”,调用其重载的方法,最后调用到Process的start方法

//frameworks\base\core\java\android\os\Process.javapublic static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();public static ProcessStartResult start(......) {return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,runtimeFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, packageName,zygotePolicyFlags, isTopApp, disabledCompatChanges,pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,

ZYGOTE_PROCESS是 ZygoteProcess类对象,调用其start方法,进而调用其startViaZygote方法

private Process.ProcessStartResult startViaZygote( ...... ){//一系列的参数设置,省略......//这里的processClass为android.app.ActivityThreadargsForZygote.add(processClass);if (extraArgs != null) {Collections.addAll(argsForZygote, extraArgs);}synchronized(mLock) {// The USAP pool can not be used if the application will not use the systems graphics// driver.  If that driver is requested use the Zygote application start path.return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),zygotePolicyFlags,argsForZygote);}}

1,调用openZygoteSocketIfNeeded 打开和 Zygote的链接
2,调用zygoteSendArgsAndGetResult发送参数并得到结果

先来看看openZygoteSocketIfNeeded 方法

	@GuardedBy("mLock")private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {try {attemptConnectionToPrimaryZygote();if (primaryZygoteState.matches(abi)) {return primaryZygoteState;}//......}@GuardedBy("mLock")private void attemptConnectionToPrimaryZygote() throws IOException {if (primaryZygoteState == null || primaryZygoteState.isClosed()) {primaryZygoteState =ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);//......}}

调用ZygoteState的connect

static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,@Nullable LocalSocketAddress usapSocketAddress)throws IOException {DataInputStream zygoteInputStream;BufferedWriter zygoteOutputWriter;final LocalSocket zygoteSessionSocket = new LocalSocket();if (zygoteSocketAddress == null) {throw new IllegalArgumentException("zygoteSocketAddress can't be null");}try {zygoteSessionSocket.connect(zygoteSocketAddress);zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());zygoteOutputWriter =new BufferedWriter(new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),Zygote.SOCKET_BUFFER_SIZE);} catch (IOException ex) {try {zygoteSessionSocket.close();} catch (IOException ignore) { }throw ex;}return new ZygoteState(zygoteSocketAddress, usapSocketAddress,zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,getAbiList(zygoteOutputWriter, zygoteInputStream));}

注意这里的 zygoteSocketAddress 即 Zygote.PRIMARY_SOCKET_NAME(zygote),调用connect连接名为zygote的socket服务,并初始化输入输出流,封装在ZygoteState对象中返回。该对象作为参数,传个zygoteSendArgsAndGetResult方法。 再来看一下zygoteSendArgsAndGetResult这个方法

@GuardedBy("mLock")private Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)throws ZygoteStartFailedEx {//......if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {try {return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);} catch (IOException ex) {// If there was an IOException using the USAP pool we will log the error and// attempt to start the process through the Zygote.Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "+ ex.getMessage());}}return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);}private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {try {final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;zygoteWriter.write(msgStr);zygoteWriter.flush();// Always read the entire result from the input stream to avoid leaving// bytes in the stream for future process starts to accidentally stumble// upon.Process.ProcessStartResult result = new Process.ProcessStartResult();result.pid = zygoteInputStream.readInt();result.usingWrapper = zygoteInputStream.readBoolean();if (result.pid < 0) {throw new ZygoteStartFailedEx("fork() failed");}return result;} catch (IOException ex) {zygoteState.close();Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "+ ex.toString());throw new ZygoteStartFailedEx(ex);}}

使用前面封装的ZygoteState 中的输入输出流,写入数据并返回结果。在 Android 11 Zygote启动流程 一文中提到,Zygote启动的时候,创建了Zygote服务端,并调用runSelectLoop,进入循环等待,等待客户端的请求。接收到请求调用processOneCommand方法。在processOneCommand方法中,先fork子进程,子进程fork成功,就在子进程中返回一个Runnable,并执行其run方法。这里的子进程是FallbackHome进程

新进程通知AMS启动FallbackHome

返回的Runnable是通过handleChildProc方法得到的

private Runnable handleChildProc(ZygoteArguments parsedArgs,FileDescriptor pipeFd, boolean isZygote) {//......Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);if (parsedArgs.mInvokeWith != null) {//} else {if (!isZygote) {return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, null /* classLoader */);} else {return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */);}}}

剩下的就和systemserver启动流程一样,只不过这里是调用前面提到的android.app.ActivityThread类的main方法 。具体参考Android 11 SystemServer启动流程。来看看ActivityThread的main方法

public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");//......Looper.prepareMainLooper();//......ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);//......Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}

创建 ActivityThread 对象并执行其attach方法

@UnsupportedAppUsageprivate void attach(boolean system, long startSeq) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManager.getService();try {mgr.attachApplication(mAppThread, startSeq);//......

获取AMS代理类对象,通过binder调用,调用AMS的attachApplication方法

@Overridepublic final void attachApplication(IApplicationThread thread, long startSeq) {if (thread == null) {throw new SecurityException("Invalid application interface");}synchronized (this) {int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid, callingUid, startSeq);Binder.restoreCallingIdentity(origId);}}

继续调用attachApplicationLocked方法

@GuardedBy("this")private boolean attachApplicationLocked(@NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {//......//创建Application并执行其oncreate方法thread.bindApplication(processName, appInfo, providerList,instr2.mClass,profilerInfo, instr2.mArguments,instr2.mWatcher,instr2.mUiAutomationConnection, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.isPersistent(),new Configuration(app.getWindowProcessController().getConfiguration()),app.compat, getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, autofillOptions, contentCaptureOptions,app.mDisabledCompatChanges);//......// See if the top visible activity is waiting to run in this process...if (normalMode) {try {didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());//启动Activity} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}}

接下来就是AMS通知FallbackHome进程,执行FallbackHome的生命周期。FallbackHome就会启动起来

FallbackHome的退出

来看一下FallbackHome的onCreate方法

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//......registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));maybeFinish();}

注册了一个ACTION_USER_UNLOCKED的广播,并在这里调用了maybeFinish方法。接收到这个广播也是调用maybeFinish

private BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {maybeFinish();}};

所以接下来看看maybeFinish到底干了什么

private void maybeFinish() {if (getSystemService(UserManager.class).isUserUnlocked()) {final Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME);final ResolveInfo homeInfo = getPackageManager().resolveActivity(homeIntent, 0);if (Objects.equals(getPackageName(), homeInfo.activityInfo.packageName)) {if (UserManager.isSplitSystemUser()&& UserHandle.myUserId() == UserHandle.USER_SYSTEM) {// This avoids the situation where the system user has no home activity after// SUW and this activity continues to throw out warnings. See b/28870689.return;}Log.d(TAG, "User unlocked but no home; let's hope someone enables one soon?");mHandler.sendEmptyMessageDelayed(0, 500);} else {Log.d(TAG, "User unlocked and real home found; let's go!");getSystemService(PowerManager.class).userActivity(SystemClock.uptimeMillis(), false);finish();}}}

如果系统已经解锁并且查找到的Launcher不是自己时就finish自己。所以可以理解为:FallbackHome注册了ACTION_USER_UNLOCKED这个广播,当接收到这个广播时,如果系统已经解锁并且查找到的Launcher不是自己时就finish自己。ACTION_USER_UNLOCKED这个广播是在哪里发出的呢?

在Android11开机动画退出流程分析一文中,有分析到,开机动画的退出是在performEnableScreen 方法中。退出开机动画后,调用AMS的bootAnimationComplete方法,然后调用到其finishBooting,我们从finishBooting开始分析

final void finishBooting() {//......mUserController.sendBootCompleted(new IIntentReceiver.Stub() {@Overridepublic void performReceive(Intent intent, int resultCode,String data, Bundle extras, boolean ordered,boolean sticky, int sendingUser) {synchronized (ActivityManagerService.this) {mOomAdjuster.mCachedAppOptimizer.compactAllSystem();requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);}}});//......}

调用到UserController对象的sendBootCompleted方法,其源码路径为frameworks\base\services\core\java\com\android\server\am\UserController.java

void sendBootCompleted(IIntentReceiver resultTo) {final boolean systemUserFinishedBooting;// Get a copy of mStartedUsers to use outside of lockSparseArray<UserState> startedUsers;synchronized (mLock) {systemUserFinishedBooting = mCurrentUserId != UserHandle.USER_SYSTEM;startedUsers = mStartedUsers.clone();}for (int i = 0; i < startedUsers.size(); i++) {UserState uss = startedUsers.valueAt(i);if (systemUserFinishedBooting && uss.mHandle.isSystem()) {// On Automotive, at this point the system user has already been started and// unlocked, and some of the tasks we do here have already been done. So skip those// in that case.// TODO(b/132262830): this workdound shouldn't be necessary once we move the// headless-user start logic to UserManager-landSlog.d(TAG, "sendBootCompleted(): skipping on non-current system user");continue;}finishUserBoot(uss, resultTo);}}

继续调用finishUserBoot,最终调用到 finishUserUnlocking

private boolean finishUserUnlocking(final UserState uss) {//......mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();//......
}

发送USER_UNLOCK_MSG消息,接收消息后,调用 finishUserUnlocked

void finishUserUnlocked(final UserState uss) {// Dispatch unlocked to external appsfinal Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);unlockedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,Binder.getCallingUid(), Binder.getCallingPid(), userId);//......finishUserUnlockedCompleted(uss);//发送开机广播}

可以看出,就是在这里发出解锁广播和开机广播的。

总结

本文简单的介绍了FallbackHome启动和关闭的代码调用流程。
启动流程主要分为以下几步

  1. Systemserver进程通过socket,通知Zygote创建新进程
  2. 新进程创建成功,新进程通知Systemserver可以启动FallbackHome
  3. Systemserver通知FallbackHome,执行其生命周期

FallbackHome退出的话,是接收到ACTION_USER_UNLOCKED广播,判断是否解锁并且查找到的Launcher不是自己时,就退出自己

http://www.dinnco.com/news/41350.html

相关文章:

  • 大连网站建设功能超级外链发布
  • 中国空间站拒绝10国名单网站推广服务
  • WordPress首页idseo网站优化服务合同
  • b2c网站怎么建设网站域名在哪里查询
  • 营业范围中网站开发与网页设计如何创建网站?
  • 西安网站建设 企业建站seo及网络推广招聘
  • 做网站需要懂程序吗淘宝运营培训班
  • 下载安装百度地图导航公众号seo排名
  • 平面素材网上海seo服务
  • 中国搜索网站提交入口怎么弄属于自己的网站
  • wordpress拖拽式布局互联网seo是什么
  • 上线了建站价格seo实战密码第四版pdf
  • 珠宝网站设计方案友情链接交易购买
  • 鲜花网站源码北京seo顾问
  • 360建筑网挂靠bim网站关键词优化推广哪家快
  • 分销系统方案首页排名关键词优化
  • 网站推广怎么做的seo案例分析
  • 怎么看网站有没有备案线上销售的方法和技巧
  • 上海长城建设有限公司网站大数据营销的概念
  • 网站怎么谈设计网络营销以什么为中心
  • 沧州免费网站建设windows优化大师官方免费下载
  • 1000并发视频网站宣传推广方案
  • 自己做网站需要收费吗seo自学网视频教程
  • 网站权重对应的等级确认已有81人感染
  • 建设企业官方网站的流程百度seo排名优化如何
  • 中国十大网站建设公司关键词优化排名工具
  • 港口建设征收 申报网站搜索引擎营销的方法
  • 邹平网站建设优化公司厦门seo推广公司
  • dw做的网站放文件夹他达拉非片正确服用方法
  • 国家市场监督管理总局服务平台seo全国最好的公司