Android开机启动流程5_第三方code

本文详细解析了Android系统的启动流程,从SystemServer.java到ActivityManagerService.java,再到ActivityStack.java等核心文件,阐述了如何启动第三方代码及初始Activity的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



这部分的代码都@frameworks\base\services\java\com\android\server\

 

SystemServer.java 

// We now tell the activity manager it is okay to run third party

        // code.  It will call back into us once it has gotten to the state

        // where third party code can really run (but before it has actually

        // started launching the initial applications), for us to complete our

        // initialization.

ActivityManagerService.self().systemReady(new Runnable() {

...

}

注:从这里开始启动第三方代码。

 

 

ActivityManagerService.java

public void systemReady(final Runnable goingCallback) {

...

mMainStack.resumeTopActivityLocked(null);

...

}

注://恢复 top activity

 

ActivityStack.java 

final boolean resumeTopActivityLocked(ActivityRecord prev) {

...

 if (next == null) {

            // There are no more activities!  Let's just start up the

            // Launcher...

            if (mMainStack) {

                return mService.startHomeActivityLocked();

            }

        }

...

}

注:因为现在没有任何启动的 activity, 将会启动 startHomeActivityLocked 

 

 

ActivityManagerService.java

  boolean startHomeActivityLocked(int userId) {

        if (mHeadless) {

            // Added because none of the other calls to ensureBootCompleted seem to fire

            // when running headless.

            ensureBootCompleted();

            return false;

        }

 

        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL

                && mTopAction == null) {

            // We are running in factory test mode, but unable to find

            // the factory test app, so just sit around displaying the

            // error message and don't try to start anything.

            return false;

        }

        Intent intent = new Intent(

            mTopAction,

            mTopData != null ? Uri.parse(mTopData) : null);

        intent.setComponent(mTopComponent);

        intent.setComponent(new ComponentName("com.amlogic.launcher", "com.amlogic.launcher.Launcher_new"));

        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {

            intent.addCategory(Intent.CATEGORY_HOME);

        }

        ActivityInfo aInfo =

            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);

        if (aInfo != null) {

            intent.setComponent(new ComponentName(

                    aInfo.applicationInfo.packageName, aInfo.name));

            // Don't do this if the home app is currently being

            // instrumented.

            aInfo = new ActivityInfo(aInfo);

            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);

            ProcessRecord app = getProcessRecordLocked(aInfo.processName,

                    aInfo.applicationInfo.uid);

            if (app == null || app.instrumentationClass == null) {

                if(SystemProperties.getBoolean("ro.tv.source_rember", false))

              {

                  if(SystemProperties.getBoolean("persist.tv.first_start", true))

                   {

                   intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);

                mMainStack.startActivityLocked(null, intent, null, aInfo,

                        null, null, 0, 0, 0, 0, null, false, null);

                   }

                  else

                  {

                  Intent intent_start_tvsetup = new Intent("com.tv.TvSetup.TvSetupService") ;

                        startService( null , intent_start_tvsetup , null ,0);

                  Log.d(TAG, "don't start Luncher for persist.tv.source_android=false");

                  }

              }

              else    

              {

                   intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);

                mMainStack.startActivityLocked(null, intent, null, aInfo,

                        null, null, 0, 0, 0, 0, null, false, null);

                  Log.d(TAG, " {" + intent.toShortString(true, true, true, false) + "} " );

                  Log.d(TAG, "startActivityLocked Luncher start");

               }

            }

        }

 

        return true;

    }

 

boolean startHomeActivityLocked() {

...

 intent.addCategory(Intent.CATEGORY_HOME);

...

}

注:启动CATEGORY_HOMEactivity

 

 

final void finishBooting() {

...

 new Intent(Intent.ACTION_BOOT_COMPLETED, null),

...

}

注:发出ACTION_BOOT_COMPLETED的广播

### 安卓平板开机启动的设置方法与解决方案 安卓平板实现开机启动的功能,通常需要结合应用开发和系统权限管理来完成。以下是详细的设置方法和解决方案: #### 1. **通过广播接收器(BroadcastReceiver)实现开机自启** 在安卓系统中,`BroadcastReceiver` 是实现开机启动的核心组件之一。以下是一个基本的实现步骤: - 在 `AndroidManifest.xml` 文件中注册广播接收器,并声明需要监听的系统广播事件 `android.intent.action.BOOT_COMPLETED`[^2]。 ```xml <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application> <receiver android:name=".BootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> </application> ``` - 创建一个广播接收器类 `BootReceiver`,并在其 `onReceive` 方法中启动所需的服务或活动: ```java public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { Intent serviceIntent = new Intent(context, MyService.class); context.startService(serviceIntent); // 启动服务 } } } ``` 需要注意的是,从 Android 3.1 开始,未运行过的应用程序无法通过广播接收器实现开机启动[^2]。因此,用户必须至少手动启动一次应用后,开机启动功能才能生效。 #### 2. **使用透明 Activity 实现开机启动** 对于某些特殊场景,可以通过创建一个透明的 `Activity` 来启动服务。这种方法可以绕过 Android 系统对未运行应用的限制。以下是实现方式: - 在 `AndroidManifest.xml` 中定义透明 Activity,并将其设置为应用的主入口: ```xml <activity android:name=".TransparentActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ``` - 在透明 Activity 的 `onCreate` 方法中启动服务并关闭 Activity: ```java public class TransparentActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent serviceIntent = new Intent(this, MyService.class); startService(serviceIntent); // 启动服务 finish(); // 关闭透明 Activity } } ``` 这种方法适用于需要快速启动服务但不希望用户看到任何界面的情况。 #### 3. **提升 APK 权限以实现系统级自启动** 如果目标设备支持 Root 或者允许刷机包安装,可以通过将 APK 提升为系统应用来实现开机启动。以下是具体步骤: - 修改 `AndroidManifest.xml` 文件,添加 `android:sharedUserId="android.uid.system"` 属性: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app" android:sharedUserId="android.uid.system"> </manifest> ``` - 使用系统签名工具对 APK 进行签名,并将其复制到 `/system/app` 目录下。此操作需要设备具备 Root 权限。 #### 4. **针对特定品牌平板的自启动权限设置** 部分品牌的安卓平板(如小米、华为等)会对第三方应用的自启动进行限制。开发者需要引导用户手动开启自启动权限。以下是一些常见品牌的设置路径: - **小米**:设置 > 电池 > 自启动管理 > 找到应用并开启自启动。 - **华为**:设置 > 电池 > 应用启动管理 > 找到应用并开启自启动。 - **三星**:设置 > 电池和设备维护 > 优化忽略列表 > 添加应用。 #### 5. **Unity 开发中的开机启动解决方案** 如果使用 Unity 开发安卓应用,可以参考项目地址 `https://gitcode.com/Universal-Tool/1e229`[^1]。该项目提供了一套简便的安卓应用开机自启解决方案,支持导入 AAR 文件实现功能集成。开发者只需按照文档说明操作即可快速实现开机启动。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值