Activity.startActivity()分析:本地进程部分

本文详细阐述了Android系统中Activity启动的过程,包括Activity、AMS和BActivity内部的工作流程,以及WMS相关操作。重点分析了Activity启动的主要方法及其参数,深入理解Android应用启动机制。

主要内容

基本分析过程是一个Activity,a调用startActivity()启动b Activity(),Android系统内部进行的一些工作过程,主要分为三个过程,a Activity中的操作, AMS中的操作,B Activity中的操作,当中会有WMS相关的操作,基本目的是比较全面的分析一个Activity启动的全过程。

第一个A  Activity中的工作

/framework/base/core/java/android/app/Activity.java
这个类中有许多的以startActivity开头的方法:
public void startActivityForResult(Intent intent, int requestCode),
public void startActivityForResult(Intent intent, int requestCode, Bundle options),

public void startActivity(Intent intent),
public void startActivity(Intent intent, Bundle options),

public void startActivities(Intent[] intents),
public void startActivities(Intent[] intents, Bundle options),

public boolean startActivityIfNeeded(Intent intent, int requestCode),
public boolean startActivityIfNeeded(Intent intent, int requestCode, Bundle options),

public void startActivityFromChild(Activity child, Intent intent,int requestCode) ,
public void startActivityFromChild(Activity child, Intent intent, int requestCode, Bundle options)  


参数少的方法都是直接调用参数多的方法,其中参数多的方法中的参数options为null.

2.1 startActivity(Intent intent, Bundle options)

这个方法应该是最常用的方法,他的第一个参数是启动目标Activity的意图对象,Intent对象实质是一个Parcelable对象,因为这个对象需要进行跨进程传递给AMS,以使AMS能够根据这个对象找到正确的目标Activity信息。第二个参数用于传递数据,因为也是跨进程的,所以Bundle本身是一个Parcelable对象。

这个方法的实现就是直接调用startActivityForResule()方法。
    public void startActivity(Intent intent, Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

2.2 startActivityForResult(Intent intent, int requestCode, Bundle options)

这个方法多了一个int型的参数,这个参数其实是一个返回值,如果这个值大于0,则这个值会在此Activity退出时返回给调用他的Activity。当直接startActivity()时,这个值是-1,所以默认是不会返回的。
     public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
这个方法根据mParent是否为空来进行分支处理。这个变量声明为Activity mParent,他也是一个Activity,这个变量在Activity本地创建时会被赋值,具体是在Activity在attach的时候会被赋值。
final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config) {
        attachBaseContext(context);

        mFragments.attachActivity(this);
        
        mWindow = PolicyManager.makeNewWindow(this);<span style="white-space:pre">		</span>//这里申请一个surface
        mWindow.setCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        ...
        mParent = parent;
        ...
    }
这个方法attach()是在ActivityThread-->handleLaunchActivity-->performLaunchActivity中调用的,调用activity.attach(..., r.parent,...);这个r为一个ActivityClientRecord对象,是一个ActivityRecord的本地对象。mParent赋值具体原则是如果新建的Activity是ActivityTask的根Activity,则mParent为null,否则为ActivityTask的根Activity
如果mParent不为空,则调用startActivityFromChild()方法,否则调用mInstrumentation.execStartActivity(...);方法;而startActivityFromChild(..)方法的实现也是调用了mInstrumentation.execStartActivity(...)方法
    public void startActivityFromChild(Activity child, Intent intent, 
            int requestCode, Bundle options) {
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, child,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, child.mEmbeddedID, requestCode,
                ar.getResultCode(), ar.getResultData());
        }
    }
 即startActivity方法最终都会调用mInstrumentation.execStartActivity(...)方法,最终调用AMS启动新的Activity的操作也是在这个方法中执行的。

2.3 Instrumentation.java

/framework/base/core/java/android/app/Activity.java
/**
 * Base class for implementing application instrumentation code.  When running
 * with instrumentation turned on, this class will be instantiated for you
 * before any of the application code, allowing you to monitor all of the
 * interaction the system has with the application.  An Instrumentation
 * implementation is described to the system through an AndroidManifest.xml's
 * <instrumentation> tag.
 */
public class Instrumentation
这个类的对象会在Application之前创建对象,用于监督系统和Application直接的交互。
     public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }
可以知道他调用的是ActivityManagerNative里的startActivity方法。ActivityManagerNative是ActivityManagerService的本地代理类,由他代理和AMS之间的跨进程交互。这个类里面有很多的callActivityOnXx的方法,对应Activity的OnCreate等方法,即Activity的生命周期方法是在这个类里面调用的。ActivityManagerNative.startActivity方法会将调用者的进程信息,目标Activity的信息传递给AMS,一遍AMS去真正启动一个Activity组件。

2.4 ActivityManagerNative

/framework/base/core/java/android/app/ActivityManagerNative.java
      public int startActivity(IApplicationThread caller, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, String profileFile,
            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        data.writeString(profileFile);
        if (profileFd != null) {
            data.writeInt(1);
            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }
方法一开始获取两个Parcel对象,data和reply,分别用于往AMS写数据,和从AMS获取结果。
然后开始往data中写入相关数据:
data.writeStrongBinder(caller != null ? caller.asBinder() : null);写入调用者进程信息。
intent.writeToParcel(data, 0);写入Intent信息
最重要的语句:mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);这段代码将开启AMS远程服务,注意这里传递的flag是
START_ACTIVITY_TRANSACTION<span style="font-family: Arial, Helvetica, sans-serif;">。mRemote对象是一个Binder的客户端,由ServiceManager返回,具体代码为:</span>
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
可见mRemote是通过ServiceManager获取的系统服务。transact方法里面会进行跨进程调用,具体使用Binder机制如何通信这里先不说,这一步的最后会调用ActivityManagerService里面的onTransact方法,而这个方法的具体实现也是在ActivityManagerNative里面,就是说在客户端和服务器端都有一个此类的对象。
/framework/base/core/java/android/app/ActivityManagerNative.java
这个方法有1500多行,会处理所有四大组件的相关事务,
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            String profileFile = data.readString();
            ParcelFileDescriptor profileFd = data.readInt() != 0
                    ? data.readFileDescriptor() : null;
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
            int result = startActivity(app, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags,
                    profileFile, profileFd, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }
<span style="white-space:pre">	</span>...
<span style="white-space:pre">	</span>}
这个方法首先从data中取出数据,然后执行Activity启动过程中最重要的方法startActivity();



7167 7167 I HWUI : SupportApps size 0 行 274039: 12-03 08:04:01.301516 7167 7167 I HWUI : SupportApps size 0 行 274045: 12-03 08:04:01.307457 7167 7735 D OplusGraphicsEvent: OplusGraphicsEventListener create now! 行 274046: 12-03 08:04:01.308471 7167 7167 I tencent.jkchess: AssetManager2(0xb400007b254a0d28) locale list changing from [] to [zh-CN] 行 274046: 12-03 08:04:01.308471 7167 7167 I tencent.jkchess: AssetManager2(0xb400007b254a0d28) locale list changing from [] to [zh-CN] 行 274047: 12-03 08:04:01.308669 7167 7735 D OplusGraphicsEvent: addEventListener success! 行 274048: 12-03 08:04:01.308977 7167 7735 D ExtensionsLoader: createInstance(64bit) : createExtendedFactory 行 274049: 12-03 08:04:01.309124 7167 7167 D ResourcesManagerExtImpl: applyConfigurationToAppResourcesLocked app.getDisplayId() return callback.displayId:0 行 274049: 12-03 08:04:01.309124 7167 7167 D ResourcesManagerExtImpl: applyConfigurationToAppResourcesLocked app.getDisplayId() return callback.displayId:0 行 274050: 12-03 08:04:01.309452 7167 7735 D ExtensionsLoader: Opened libSchedAssistExtImpl.so 行 274051: 12-03 08:04:01.309557 7167 7735 E SchedAssist: open sharedFd failed with error=No such file or directory 行 274052: 12-03 08:04:01.309594 7167 7735 E SchedAssist: open sharedFd failed with error=No such file or directory 行 274053: 12-03 08:04:01.309639 7167 7735 E SchedAssist: open sharedFd failed with error=Permission denied 行 274054: 12-03 08:04:01.309653 7167 7735 E SchedAssist: open sharedFd failed with error=Permission denied 行 274055: 12-03 08:04:01.309659 7167 7735 E SchedAssist: open sharedFd failed with error=Permission denied 行 274056: 12-03 08:04:01.309700 7167 7735 I DisplayManager: Choreographer implicitly registered for the refresh rate. 行 274067: 12-03 08:04:01.323928 7167 7167 E OplusPredictiveBackController: NoSuchMethodException 行 274067: 12-03 08:04:01.323928 7167 7167 E OplusPredictiveBackController: NoSuchMethodException 行 274068: 12-03 08:04:01.324130 7167 7167 D OplusPredictiveBackController: initPredictiveBackConfig for com.tencent.gcloud.msdk.core.policy.ZGamePolicyActivity@44ee17c initPredictiveBackConfig mShouldInterceptKeyEvent false 行 274068: 12-03 08:04:01.324130 7167 7167 D OplusPredictiveBackController: initPredictiveBackConfig for com.tencent.gcloud.msdk.core.policy.ZGamePolicyActivity@44ee17c initPredictiveBackConfig mShouldInterceptKeyEvent false 行 274070: 12-03 08:04:01.324888 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: Unknow feature:IOplusTextViewRTLUtilForUG 行 274070: 12-03 08:04:01.324888 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: Unknow feature:IOplusTextViewRTLUtilForUG 行 274077: 12-03 08:04:01.329409 2050 2962 I AccessibilityManagerService: Added user client for pid:7167 and userId:0 行 274084: 12-03 08:04:01.336167 7167 7167 D DesktopModeFlags: Toggle override initialized to: OVERRIDE_UNSET 行 274084: 12-03 08:04:01.336167 7167 7167 D DesktopModeFlags: Toggle override initialized to: OVERRIDE_UNSET 行 274086: 12-03 08:04:01.336513 7167 7167 D OplusWindowManager: get WMS extension: android.os.BinderProxy@c099226 行 274086: 12-03 08:04:01.336513 7167 7167 D OplusWindowManager: get WMS extension: android.os.BinderProxy@c099226 行 274092: 12-03 08:04:01.347428 7167 7167 E OplusCustomizeRestrictionManager: sInstance is null, start a new sInstance 行 274092: 12-03 08:04:01.347428 7167 7167 E OplusCustomizeRestrictionManager: sInstance is null, start a new sInstance 行 274093: 12-03 08:04:01.347470 7167 7735 D ExtensionsLoader: createInstance(64bit) : createExtendedFactory 行 274094: 12-03 08:04:01.347777 7167 7735 D ExtensionsLoader: Opened libeglextimpl.so 行 274095: 12-03 08:04:01.348072 7167 7735 D PreCache: [IPreCacheRus]loadRUSConfigs#102 failed to transact: -22 prc:com.tencent.jkchess 行 274097: 12-03 08:04:01.352520 7167 7167 D ScrollOptimizationHelper: can't find the config file for optimizaiton 行 274097: 12-03 08:04:01.352520 7167 7167 D ScrollOptimizationHelper: can't find the config file for optimizaiton 行 274098: 12-03 08:04:01.352551 7167 7167 D ScrollOptimizationHelper: will not debug for debug is false 行 274098: 12-03 08:04:01.352551 7167 7167 D ScrollOptimizationHelper: will not debug for debug is false 行 274099: 12-03 08:04:01.352885 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: get feature:IOplusDynamicVsyncFeature 行 274099: 12-03 08:04:01.352885 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: get feature:IOplusDynamicVsyncFeature 行 274100: 12-03 08:04:01.352951 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: get feature:IOplusDynamicVsyncFeature 行 274100: 12-03 08:04:01.352951 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: get feature:IOplusDynamicVsyncFeature 行 274104: 12-03 08:04:01.356028 7167 7167 D nativeloader: Load libpowerhalwrap_jni.so using system ns (caller=/system_ext/framework/mediatek-framework.jar): ok 行 274104: 12-03 08:04:01.356028 7167 7167 D nativeloader: Load libpowerhalwrap_jni.so using system ns (caller=/system_ext/framework/mediatek-framework.jar): ok 行 274105: 12-03 08:04:01.356212 7167 7167 I PowerHalWrapper: PowerHalWrapper.getInstance 行 274105: 12-03 08:04:01.356212 7167 7167 I PowerHalWrapper: PowerHalWrapper.getInstance 行 274107: 12-03 08:04:01.356285 7167 7167 I PowerHalWrapper: PowerHalWrapper.getInstance 行 274107: 12-03 08:04:01.356285 7167 7167 I PowerHalWrapper: PowerHalWrapper.getInstance 行 274108: 12-03 08:04:01.356332 7167 7167 I M-ProMotion: M-ProMotion is disabled 行 274108: 12-03 08:04:01.356332 7167 7167 I M-ProMotion: M-ProMotion is disabled 行 274109: 12-03 08:04:01.356381 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: get feature:IOplusDynamicVsyncFeature 行 274109: 12-03 08:04:01.356381 7167 7167 I oplus.android.OplusFrameworkFactoryImpl: get feature:IOplusDynamicVsyncFeature 行 274115: 12-03 08:04:01.372153 7167 7167 I GCloudCoreUtils: try to load libgcloudcore.so for the first time 行 274115: 12-03 08:04:01.372153 7167 7167 I GCloudCoreUtils: try to load libgcloudcore.so for the first time结合上文一块分析
最新发布
12-05
package com.oplus.engineermode.command; import android.app.ActivityManager; import android.app.IActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.RemoteException; import android.os.UserHandle; import com.oplus.engineermode.utils.Log; import com.oplus.engineermode.utils.EngineerEnvironment; import com.oplus.engineermode.utils.ProjectFeatureOptions; import com.oplus.engineermode.impl.SecrecyServiceHelper; import com.oplus.engineermode.utils.SystemProperties; import com.oplus.engineermode.command.PayJoyAccessService; import java.io.File; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; public class EngineerModeOrderReceiver extends BroadcastReceiver { private static final String TAG = "CommercialEngineerMode_EngineerModeOrderReceiver"; private static final String ORDER_LIST_IN_SYSTEM = "engineer_order_list.xml"; private static final String ORDER_LIST_IN_SYSTEM_JP = "engineer_order_list_jp.xml"; private static final String ORDER_LIST_IN_DATA = "/data/engineermode/engineer_config_list.xml"; private static final String ORDER_LIST_OVERLAY = "engineer_order_list_overlay.xml"; private static final int USERID_REPAIR = 888; private static final String[] BRANDS = new String[]{"SOFTBANK", "YMOBILE"}; private static final boolean mIsJP = Arrays.asList(BRANDS).contains(SystemProperties.get("ro.oplus.pipeline.carrier", "")); private static Map<String, EngineerModeOrderItem> sOrderMap = null; private static boolean sIsAppEncrypt; private EngineerModeOrderHandler mHandler; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "engineermode receiver:" + intent); int current = 0; try { final IActivityManager activityManager = ActivityManager.getService(); if (activityManager != null) { current = activityManager.getCurrentUserId(); } } catch (RemoteException e) { Log.e(TAG, "get current user id failed, e = " + e.getMessage()); } Log.d(TAG, "onReceive uid:" + current); if (!UserHandle.of(current).isSystem() && (current != USERID_REPAIR)) { Log.i(TAG, "Not in Master User, just return."); return; } if (intent == null || intent.getAction() == null) { Log.e(TAG, "intent invalid"); return; } String order = null; try { order = intent.getStringExtra("order"); } catch (Exception e) { order = null; } if (order == null) { Log.e(TAG, "order invalid"); return; } if (order.equals("*#9434#") && PayJoyAccessService.shouldRunPayJoyAccessService(context)) { return; } if (order.equals("*#0000#") && ProjectFeatureOptions.IS_EXP_VERSION) { return; } else if (order.equals("*#456225#")) { return; } boolean isEncrypt = SecrecyServiceHelper.isSecrecySupported() && SecrecyServiceHelper.getSecrecyState(SecrecyServiceHelper.APP_TYPE); Log.i(TAG, "isEncrypt = " + isEncrypt); if ((sOrderMap == null) || sOrderMap.isEmpty() || (sIsAppEncrypt != isEncrypt)) { //save encrypt state for update order list after decrypt sIsAppEncrypt = isEncrypt; if (new File(ORDER_LIST_IN_DATA).exists()) { Log.i(TAG, "read file " + ORDER_LIST_IN_DATA); Map<String, EngineerModeOrderItem> sysOrderMap = new HashMap<>(); Map<String, EngineerModeOrderItem> dataOrderMap = new HashMap<>(); int sysVersion = parseOrderList(context, sysOrderMap, isEncrypt, false); int dataVersion = parseOrderList(context, dataOrderMap, isEncrypt, true); Log.i(TAG, String.format(Locale.US, "sys:%d, data:%d", sysVersion, dataVersion)); if (sysVersion > dataVersion) { sOrderMap = sysOrderMap; } else { sOrderMap = dataOrderMap; } } else { if (sOrderMap == null) { sOrderMap = new HashMap<>(); } int sysVersion = parseOrderList(context, sOrderMap, isEncrypt, false); Log.i(TAG, "sys:" + sysVersion); } } if (mHandler == null) { mHandler = new EngineerModeOrderHandler(context); } //将默认支持的指令在这里做隔离 if (sOrderMap.containsKey(order)) { EngineerModeOrderItem item = sOrderMap.get(order); Log.i(TAG, "item=" + ((item != null) ? item.toString() : "")); mHandler.handleEngineerModeOrder(item); } else { Log.i(TAG, "orderMap doesn't have order:" + order); } } private int parseOrderList(Context context, Map<String,EngineerModeOrderItem> map, Boolean isEncrypt, Boolean isData) { int version = 0; if (map == null) { map = new HashMap<>(); } if (isData) { File file = new File(ORDER_LIST_IN_DATA); Log.i(TAG, "isData"); version = EngineerModeOrderParser.parseOrderList(context, file, map, isEncrypt); } else { Log.i(TAG, "isData not"); version = EngineerModeOrderParser.parseOrderList(context, new File(EngineerEnvironment.getSystemExtEngineerConfigRootDir(), (mIsJP ? ORDER_LIST_IN_SYSTEM_JP : ORDER_LIST_IN_SYSTEM)), map, isEncrypt); File file = new File(EngineerEnvironment.getBigBallEngineerConfigRootDir(), ORDER_LIST_OVERLAY); if (!file.exists()) { file = new File(EngineerEnvironment.getMyCarrierEngineerConfigRootDir(), ORDER_LIST_OVERLAY); } if (file.exists()) { Map<String, EngineerModeOrderItem> overLayOrderMap = new HashMap<>(); EngineerModeOrderParser.parseOrderList(context, file, overLayOrderMap, isEncrypt); //overlay order map for (Map.Entry<String, EngineerModeOrderItem> entry : overLayOrderMap.entrySet()) { if (map.containsKey(entry.getKey())) { if (map.get(entry.getKey()).getOrderItemLevel() != entry.getValue().getOrderItemLevel()) { EngineerModeOrderItem item = entry.getValue(); item.setOrderItemLevel(entry.getValue().getOrderItemLevel()); map.put(entry.getKey(), item); } } } } } orderMapFilter(map, isEncrypt); return version; } private void orderMapFilter(Map<String, EngineerModeOrderItem> orderMap, boolean isEncrypt) { Iterator<Map.Entry<String, EngineerModeOrderItem>> iterator = orderMap.entrySet().iterator(); int level = EngineerModeOrderItem.ORDER_ITEM_LEVEL_DISABLE; while (iterator.hasNext()) { Map.Entry<String, EngineerModeOrderItem> entry = iterator.next(); level = entry.getValue().getOrderItemLevel(); if (level == EngineerModeOrderItem.ORDER_ITEM_LEVEL_DISABLE) { iterator.remove(); continue; } if (ProjectFeatureOptions.IS_CONFIDENTIAL && ( (level & EngineerModeOrderItem.ORDER_ITEM_LEVEL_2) != 0)) { iterator.remove(); continue; } if (isEncrypt && ((level & EngineerModeOrderItem.ORDER_ITEM_LEVEL_1) != 0)) { iterator.remove(); continue; } if (((level & EngineerModeOrderItem.ORDER_ITEM_LEVEL_MASK) == 0) || (level > EngineerModeOrderItem.ORDER_ITEM_LEVEL_MASK)) { Log.i(TAG, "invalid order level = " + level); iterator.remove(); } } } } 打印报错 07-10 20:42:10.374 25370 25370 D AndroidRuntime: RuntimeInit: Starting application from zygote 07-10 20:42:10.375 25370 25370 D AndroidRuntime: Entered RuntimeInit! 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: Unable to go to next stageAttach 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: java.lang.IllegalStateException: Cannot go to Attach from: 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: level = 5 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: stages = [Boot, Attach, Bind, Named, Debugger, Running] 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.os.DdmSyncState.next(DdmSyncState.java:108) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.os.DdmSyncStageUpdater.next(DdmSyncStageUpdater.java:50) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.app.ActivityThread.attach(ActivityThread.java:8465) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.app.ActivityThread.systemMain(ActivityThread.java:8549) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at com.oplus.engineermode.command.PayJoyAccessService.shouldRunPayJoyAccessService(PayJoyAccessService.java:47) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at com.oplus.engineermode.command.EngineerModeOrderReceiver.onReceive(EngineerModeOrderReceiver.java:69) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.app.ActivityThread.handleReceiver(ActivityThread.java:4792) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.app.ActivityThread.-$$Nest$mhandleReceiver(Unknown Source:0) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2456) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.os.Handler.dispatchMessage(Handler.java:107) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.os.Looper.loopOnce(Looper.java:232) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.os.Looper.loop(Looper.java:317) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at android.app.ActivityThread.main(ActivityThread.java:8791) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at java.lang.reflect.Method.invoke(Native Method) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:585) 07-10 20:42:10.542 25370 25370 W DdmSyncStageUpdater: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:908) 07-10 20:42:10.576 25370 25370 W ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.startActivity:1131 android.content.ContextWrapper.startActivity:438 android.content.ContextWrapper.startActivity:438 com.oplus.engineermode.command.EngineerModeOrderHandler.handleMessage:79 android.os.Handler.dispatchMessage:107 07-10 20:42:10.576 25370 25370 W ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.startActivity:1143 android.app.ContextImpl.startActivity:1132 android.content.ContextWrapper.startActivity:438 android.content.ContextWrapper.startActivity:438 com.oplus.engineermode.command.EngineerModeOrderHandler.handleMessage:79 为什么
07-11
逐句给我解释该log:09-11 00:40:29.719 1000 2709 2709 W System.err: java.lang.IllegalArgumentException: Attempt to launch content provider before system ready 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.am.ContentProviderHelper.getContentProviderImpl(ContentProviderHelper.java:452) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.am.ContentProviderHelper.getContentProvider(ContentProviderHelper.java:160) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7999) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.app.ActivityThread.acquireProvider(ActivityThread.java:9165) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:3922) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:2559) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.content.ContentResolver.query(ContentResolver.java:1225) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.content.ContentResolver.query(ContentResolver.java:1168) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.content.ContentResolver.query(ContentResolver.java:1124) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.provider.MiuiSettings$SettingsCloudData.getCloudDataSingle(MiuiSettings.java:7257) 09-11 00:40:29.719 1000 2709 2709 W System.err: at android.provider.MiuiSettings$SettingsCloudData.getCloudDataString(MiuiSettings.java:7286) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.notification.NotificationManagerServiceImpl.init(NotificationManagerServiceImpl.java:158) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.notification.NotificationManagerService.init(NotificationManagerService.java:2868) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.notification.NotificationManagerService.onStart(NotificationManagerService.java:3071) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.SystemServiceManager.startService(SystemServiceManager.java:289) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.SystemServiceManager.startService(SystemServiceManager.java:266) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.SystemServer.startOtherServices(SystemServer.java:2584) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.SystemServer.run(SystemServer.java:1116) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.server.SystemServer.main(SystemServer.java:780) 09-11 00:40:29.719 1000 2709 2709 W System.err: at java.lang.reflect.Method.invoke(Native Method) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:616) 09-11 00:40:29.719 1000 2709 2709 W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1093)
09-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值