Am.java
public static void main(String[] args) {
(new Am()).run(args);
}
public void run(String[] args) {
if (args.length < 1) {
onShowUsage(System.out);
return;
}
mRawArgs = args;//参数交给了mRawArgs
mArgs.init(null, null, null, null, args, null, 0);
try {
onRun();
} catch (IllegalArgumentException e) {
...
} catch (Exception e) {
...
System.exit(1);
}
}
@Override
public void onRun() throws Exception {
//AMS
mAm = ActivityManager.getService();
//PKMS
mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
String op = nextArgRequired();
if (op.equals("instrument")) {
runInstrument();
} else {
runAmCmd(getRawArgs());
}
}
void runAmCmd(String[] args) throws AndroidException {
final MyShellCallback cb = new MyShellCallback();
try {
mAm.asBinder().shellCommand(FileDescriptor.in, FileDescriptor.out, FileDescriptor.err,
args, cb, new ResultReceiver(null) { });
} catch (RemoteException e) {
System.err.println(NO_SYSTEM_ERROR_CODE);
throw new AndroidException("Can't call activity manager; is the system running?");
} finally {
cb.mActive = false;
}
}
其中shellCommand( )进入到AMS中,因为AMS也是继承Binder,该方法是Binder拥有
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out,
FileDescriptor err, String[] args, ShellCallback callback,
ResultReceiver resultReceiver) {
(new ActivityManagerShellCommand(this, false)).exec(
this, in, out, err, args, callback, resultReceiver);
}
最终执行到,通过以下代码可以看出命令支持相当丰富。
ActivityManagerShellCommand.java
@Override
public int onCommand(String cmd) {
if (cmd == null) {
return handleDefaultCommands(cmd);
}
PrintWriter pw = getOutPrintWriter();
try {
switch (cmd) {
case "start":
case "start-activity":
return runStartActivity(pw);
case "startservice":
case "start-service":
return runStartService(pw, false);
...
}
} catch (RemoteException e) {
pw.println("Remote exception: " + e);
}
return -1;
}
int runStartActivity(PrintWriter pw) throws RemoteException {
...
return 0;
}
runStartActivity方法比较长,我们就分成若干部分进行分析。
Intent intent;
try {
intent = makeIntent(UserHandle.USER_CURRENT);//解析Intent
} catch (URISyntaxException e) {
throw new RuntimeException(e.getMessage(), e);
}
主要是启动Activity命令am start [options]
使用options参数,接下来列举Activity命令的[options]参数:
>: 重复启动Activity COUNT次
> |
current: 指定用户来运行App,默认为当前用户。
>: 启动profiler,并将结果发送到 >;
>: 类似 –start-profiler,不同的是当app进入idle状态,则停止profiling
总之在如下语句中,能对应到所有支持的参数,并转化成AMS可用类型的数据结构
private Intent makeIntent(int defUser) throws URISyntaxException {
mStartFlags = 0;
mWaitOption = false;
mStopOption = false;
mRepeat = 0;
mProfileFile = null;
mSamplingInterval = 0;
mAutoStop = false;
mStreaming = false;
mUserId = defUser;
mDisplayId = INVALID_DISPLAY;
mStackId = INVALID_STACK_ID;
mTaskId = INVALID_TASK_ID;
mIsTaskOverlay = false;
return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
@Override
public boolean handleOption(String opt, ShellCommand cmd) {
if (opt.equals("-D")) {
//允许调试
mStartFlags |= ActivityManager.START_FLAG_DEBUG;
} else if (opt.equals("-N")) {
mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
} else if (opt.equals("-W")) {
//等待app启动完成
mWaitOption = true;
} else if (opt.equals("-P")) {
//类似 –start-profiler,不同的是当app进入idle状态,则停止profiling
mProfileFile = getNextArgRequired();
mAutoStop = true;
} else if (opt.equals("--start-profiler")) {
//启动profiler,并将结果发送到 ;
mProfileFile = getNextArgRequired();
mAutoStop = false;
} else if (opt.equals("--sampling")) {
//设置profiler 取样时间间隔,单位ms;
mSamplingInterval = Integer.parseInt(getNextArgRequired());
} else if (opt.equals("--streaming")) {
mStreaming = true;
} else if (opt.equals("--attach-agent")) {
if (mAgent != null) {
cmd.getErrPrintWriter().println(
"Multiple --attach-agent(-bind) not supported");
return false;
}
mAgent = getNextArgRequired();
mAttachAgentDuringBind = false;
} else if (opt.equals("--attach-agent-bind")) {
if (mAgent != null) {
cmd.getErrPrintWriter().println(
"Multiple --attach-agent(-bind) not supported");
return false;
}
mAgent = getNextArgRequired();
mAttachAgentDuringBind = true;
} else if (opt.equals("-R")) {
// 重复启动Activity COUNT次
mRepeat = Integer.parseInt(getNextArgRequired());
} else if (opt.equals("-S")) {
//启动activity之前,先调用forceStopPackage()方法强制停止app.
mStopOption = true;
} else if (opt.equals("--track-allocation")) {
mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
} else if (opt.equals("--user")) {
mUserId = UserHandle.parseUserArg(getNextArgRequired());
} else if (opt.equals("--receiver-permission")) {
mReceiverPermission = getNextArgRequired();
} else if (opt.equals("--display")) {
mDisplayId = Integer.parseInt(getNextArgRequired());
} else if (opt.equals("--stack")) {
mStackId = Integer.parseInt(getNextArgRequired());
} else if (opt.equals("--task")) {
mTaskId = Integer.parseInt(getNextArgRequired());
} else if (opt.equals("--task-overlay")) {
mIsTaskOverlay = true;
} else {
return false;
}
return true;
}
});
}
/** @hide */
public static Intent parseCommandArgs(ShellCommand cmd, CommandOptionHandler optionHandler)
throws URISyntaxException {
Intent intent = new Intent();
Intent baseIntent = intent;
boolean hasIntentInfo = false;
Uri data = null;
String type = null;
String opt;
//通过从参数中读取
while ((opt=cmd.getNextOption()) != null) {
switch (opt) {
case "-a":
//设置Action的是下一个参数,比如android.intent.action.VIEW
intent.setAction(cmd.getNextArgRequired());
if (intent == baseIntent) {
hasIntentInfo = true;
}
break;
case "-d":
//通过uri解析数据。比如http://xxx.com
data = Uri.parse(cmd.getNextArgRequired());
if (intent == baseIntent) {
hasIntentInfo = true;
}
break;
case "-t":
type = cmd.getNextArgRequired();
if (intent == baseIntent) {
hasIntentInfo = true;
}
break;
case "-c":
intent.addCategory(cmd.getNextArgRequired());
if (intent == baseIntent) {
hasIntentInfo = true;
}
break;
case "-e":
case "--es": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
intent.putExtra(key, value);
}
break;
case "--esn": {
String key = cmd.getNextArgRequired();
intent.putExtra(key, (String) null);
}
break;
case "--ei": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
intent.putExtra(key, Integer.decode(value));
}
break;
case "--eu": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
intent.putExtra(key, Uri.parse(value));
}
break;
case "--ecn": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
ComponentName cn = ComponentName.unflattenFromString(value);
if (cn == null)
throw new IllegalArgumentException("Bad component name: " + value);
intent.putExtra(key, cn);
}
break;
case "--eia": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
String[] strings = value.split(",");
int[] list = new int[strings.length];
for (int i = 0; i < strings.length; i++) {
list[i] = Integer.decode(strings[i]);
}
intent.putExtra(key, list);
}
break;
case "--eial": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
String[] strings = value.split(",");
ArrayList<Integer> list = new ArrayList<>(strings.length);
for (int i = 0; i < strings.length; i++) {
list.add(Integer.decode(strings[i]));
}
intent.putExtra(key, list);
}
break;
case "--el": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
intent.putExtra(key, Long.valueOf(value));
}
break;
case "--ela": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
String[] strings = value.split(",");
long[] list = new long[strings.length];
for (int i = 0; i < strings.length; i++) {
list[i] = Long.valueOf(strings[i]);
}
intent.putExtra(key, list);
hasIntentInfo = true;
}
break;
case "--elal": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
String[] strings = value.split(",");
ArrayList<Long> list = new ArrayList<>(strings.length);
for (int i = 0; i < strings.length; i++) {
list.add(Long.valueOf(strings[i]));
}
intent.putExtra(key, list);
hasIntentInfo = true;
}
break;
case "--ef": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
intent.putExtra(key, Float.valueOf(value));
hasIntentInfo = true;
}
break;
case "--efa": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
String[] strings = value.split(",");
float[] list = new float[strings.length];
for (int i = 0; i < strings.length; i++) {
list[i] = Float.valueOf(strings[i]);
}
intent.putExtra(key, list);
hasIntentInfo = true;
}
break;
case "--efal": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
String[] strings = value.split(",");
ArrayList<Float> list = new ArrayList<>(strings.length);
for (int i = 0; i < strings.length; i++) {
list.add(Float.valueOf(strings[i]));
}
intent.putExtra(key, list);
hasIntentInfo = true;
}
break;
case "--esa": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
// Split on commas unless they are preceeded by an escape.
// The escape character must be escaped for the string and
// again for the regex, thus four escape characters become one.
String[] strings = value.split("(?);
intent.putExtra(key, strings);
hasIntentInfo = true;
}
break;
case "--esal": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired();
// Split on commas unless they are preceeded by an escape.
// The escape character must be escaped for the string and
// again for the regex, thus four escape characters become one.
String[] strings = value.split("(?);
ArrayList<String> list = new ArrayList<>(strings.length);
for (int i = 0; i < strings.length; i++) {
list.add(strings[i]);
}
intent.putExtra(key, list);
hasIntentInfo = true;
}
break;
case "--ez": {
String key = cmd.getNextArgRequired();
String value = cmd.getNextArgRequired().toLowerCase();
// Boolean.valueOf() results in false for anything that is not "true", which is
// error-prone in shell commands
boolean arg;
if ("true".equals(value) || "t".equals(value)) {
arg = true;
} else if ("false".equals(value) || "f".equals(value)) {
arg = false;
} else {
try {
arg = Integer.decode(value) != 0;
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Invalid boolean value: " + value);
}
}
intent.putExtra(key, arg);
}
break;
case "-n": {
String str = cmd.getNextArgRequired();
ComponentName cn = ComponentName.unflattenFromString(str);
if (cn == null)
throw new IllegalArgumentException("Bad component name: " + str);
intent.setComponent(cn);
if (intent == baseIntent) {
hasIntentInfo = true;
}
}
break;
case "-p": {
String str = cmd.getNextArgRequired();
intent.setPackage(str);
if (intent == baseIntent) {
hasIntentInfo = true;
}
}
break;
case "-f":
String str = cmd.getNextArgRequired();
intent.setFlags(Integer.decode(str).intValue());
break;
case "--grant-read-uri-permission":
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
break;
case "--grant-write-uri-permission":
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
break;
case "--grant-persistable-uri-permission":
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
break;
case "--grant-prefix-uri-permission":
intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
break;
case "--exclude-stopped-packages":
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
break;
case "--include-stopped-packages":
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
break;
case "--debug-log-resolution":
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
break;
case "--activity-brought-to-front":
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
break;
case "--activity-clear-top":
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
break;
case "--activity-clear-when-task-reset":
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
break;
case "--activity-exclude-from-recents":
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
break;
case "--activity-launched-from-history":
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
break;
case "--activity-multiple-task":
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
break;
case "--activity-no-animation":
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
break;
case "--activity-no-history":
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
break;
case "--activity-no-user-action":
intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
break;
case "--activity-previous-is-top":
intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
break;
case "--activity-reorder-to-front":
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
break;
case "--activity-reset-task-if-needed":
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
break;
case "--activity-single-top":
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
break;
case "--activity-clear-task":
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
break;
case "--activity-task-on-home":
intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
break;
case "--receiver-registered-only":
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
break;
case "--receiver-replace-pending":
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
break;
case "--receiver-foreground":
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
break;
case "--receiver-no-abort":
intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
break;
case "--receiver-include-background":
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
break;
case "--selector":
intent.setDataAndType(data, type);
intent = new Intent();
break;
default:
if (optionHandler != null && optionHandler.handleOption(opt, cmd)) {
// Okay, caller handled this option.
} else {
throw new IllegalArgumentException("Unknown option: " + opt);
}
break;
}
}
intent.setDataAndType(data, type);
final boolean hasSelector = intent != baseIntent;
if (hasSelector) {
// A selector was specified; fix up.
baseIntent.setSelector(intent);
intent = baseIntent;
}
String arg = cmd.getNextArg();
baseIntent = null;
if (arg == null) {
if (hasSelector) {
// If a selector has been specified, and no arguments
// have been supplied for the main Intent, then we can
// assume it is ACTION_MAIN CATEGORY_LAUNCHER; we don't
// need to have a component name specified yet, the
// selector will take care of that.
baseIntent = new Intent(Intent.ACTION_MAIN);
baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
}
} else if (arg.indexOf(':') >= 0) {
// The argument is a URI. Fully parse it, and use that result
// to fill in any data not specified so far.
baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME
| Intent.URI_ANDROID_APP_SCHEME | Intent.URI_ALLOW_UNSAFE);
} else if (arg.indexOf('/') >= 0) {
// The argument is a component name. Build an Intent to launch
// it.
baseIntent = new Intent(Intent.ACTION_MAIN);
baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
baseIntent.setComponent(ComponentName.unflattenFromString(arg));
} else {
// Assume the argument is a package name.
baseIntent = new Intent(Intent.ACTION_MAIN);
baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
baseIntent.setPackage(arg);
}
if (baseIntent != null) {
Bundle extras = intent.getExtras();
intent.replaceExtras((Bundle)null);
Bundle uriExtras = baseIntent.getExtras();
baseIntent.replaceExtras((Bundle)null);
if (intent.getAction() != null && baseIntent.getCategories() != null) {
HashSet<String> cats = new HashSet<String>(baseIntent.getCategories());
for (String c : cats) {
baseIntent.removeCategory(c);
}
}
intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_SELECTOR);
if (extras == null) {
extras = uriExtras;
} else if (uriExtras != null) {
uriExtras.putAll(extras);
extras = uriExtras;
}
intent.replaceExtras(extras);
hasIntentInfo = true;
}
if (!hasIntentInfo) throw new IllegalArgumentException("No intent supplied");
return intent;
}
/** @hide */
public static void printIntentArgsHelp(PrintWriter pw, String prefix) {
final String[] lines = new String[] {
" specifications include these flags and arguments:" ,
" [-a ] [-d ] [-t ]" ,
" [-c [-c ] ...]" ,
" [-e|--es ...]" ,
" [--esn ...]" ,
" [--ez ...]" ,
" [--ei ...]" ,
" [--el ...]" ,
" [--ef ...]" ,
" [--eu ...]" ,
" [--ecn ]" ,
" [--eia [,,
" (mutiple extras passed as Integer[])",
" [--eial [,,
" (mutiple extras passed as List)" ,
" [--ela [,,
" (mutiple extras passed as Long[])",
" [--elal [,,
" (mutiple extras passed as List)" ,
" [--efa [,,
" (mutiple extras passed as Float[])",
" [--efal [,,
" (mutiple extras passed as List)" ,
" [--esa [,,
" (mutiple extras passed as String[]; to embed a comma into a string,",
" escape it using \"\\,\")",
" [--esal [,,
" (mutiple extras passed as List; to embed a comma into a string," ,
" escape it using \"\\,\")",
" [-f ]" ,
" [--grant-read-uri-permission] [--grant-write-uri-permission]",
" [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]",
" [--debug-log-resolution] [--exclude-stopped-packages]",
" [--include-stopped-packages]",
" [--activity-brought-to-front] [--activity-clear-top]",
" [--activity-clear-when-task-reset] [--activity-exclude-from-recents]",
" [--activity-launched-from-history] [--activity-multiple-task]",
" [--activity-no-animation] [--activity-no-history]",
" [--activity-no-user-action] [--activity-previous-is-top]",
" [--activity-reorder-to-front] [--activity-reset-task-if-needed]",
" [--activity-single-top] [--activity-clear-task]",
" [--activity-task-on-home]",
" [--receiver-registered-only] [--receiver-replace-pending]",
" [--receiver-foreground] [--receiver-no-abort]",
" [--receiver-include-background]",
" [--selector]",
" [ | | ]"
};
for (String line : lines) {
pw.print(prefix);
pw.println(line);
}
}
//写入对应在-t参数type = cmd.getNextArgRequired();
//data是通过-d参数
//intent.setDataAndType(data, type);内部通过mType = type;
String mimeType = intent.getType();
if (mimeType == null && intent.getData() != null
&& "content".equals(intent.getData().getScheme())) {
mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId);
}
do {
//该参数通过-S指定,表示启动activity之前,先调用forceStopPackage()方法强制停止app
if (mStopOption) {
String packageName;
//通过-n指定启动的组件名
if (intent.getComponent() != null) {
packageName = intent.getComponent().getPackageName();
} else {
List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
mUserId).getList();
if (activities == null || activities.size() <= 0) {
getErrPrintWriter().println("Error: Intent does not match any activities: "
+ intent);
return 1;
} else if (activities.size() > 1) {
getErrPrintWriter().println(
"Error: Intent matches multiple activities; can't stop: "
+ intent);
return 1;
}
packageName = activities.get(0).activityInfo.packageName;
}
//上面这段话目的是寻找指定intent对应的包名
pw.println("Stopping: " + packageName);
pw.flush();
//这句话通过pm.setPackageStoppedState(packageName, true, user);设置标记
mInterface.forceStopPackage(packageName, mUserId);
try {
Thread.sleep(250);
} catch (InterruptedException e) {
}
if (mProfileFile != null || mAgent != null) {
ParcelFileDescriptor fd = null;
if (mProfileFile != null) {
fd = openOutputFileForSystem(mProfileFile);
if (fd == null) {
return 1;
}
}
profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
mStreaming, mAgent, mAttachAgentDuringBind);
}
pw.println("Starting: " + intent);
pw.flush();
//设置新栈
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
WaitResult result = null;
int res;
final long startTime = SystemClock.uptimeMillis();
ActivityOptions options = null;
//通过--display指定,默认为INVALID_DISPLAY
if (mDisplayId != INVALID_DISPLAY) {
options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(mDisplayId);
}
//通过--stack指定,默认是INVALID_STACK_ID
if (mStackId != INVALID_STACK_ID) {
options = ActivityOptions.makeBasic();
options.setLaunchStackId(mStackId);
}
//通过--task
if (mTaskId != INVALID_TASK_ID) {
options = ActivityOptions.makeBasic();
options.setLaunchTaskId(mTaskId);
if (mIsTaskOverlay) {
options.setTaskOverlay(true, true /* canResume */);
}
}
//通过-W指定,表示是否等待app启动完成
if (mWaitOption) {
result = mInterface.startActivityAndWait(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
res = result.result;
} else {
res = mInterface.startActivityAsUser(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
}
final long endTime = SystemClock.uptimeMillis();
PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
boolean launched = false;
//通过返回的标记,做对应的处理
switch (res) {
case ActivityManager.START_SUCCESS:
launched = true;
break;
case ActivityManager.START_SWITCHES_CANCELED:
launched = true;
out.println(
"Warning: Activity not started because the "
+ " current activity is being kept for the user.");
break;
case ActivityManager.START_DELIVERED_TO_TOP:
launched = true;
out.println(
"Warning: Activity not started, intent has "
+ "been delivered to currently running "
+ "top-most instance.");
break;
case ActivityManager.START_RETURN_INTENT_TO_CALLER:
launched = true;
out.println(
"Warning: Activity not started because intent "
+ "should be handled by the caller");
break;
case ActivityManager.START_TASK_TO_FRONT:
launched = true;
out.println(
"Warning: Activity not started, its current "
+ "task has been brought to the front");
break;
case ActivityManager.START_INTENT_NOT_RESOLVED:
out.println(
"Error: Activity not started, unable to "
+ "resolve " + intent.toString());
break;
case ActivityManager.START_CLASS_NOT_FOUND:
out.println(NO_CLASS_ERROR_CODE);
out.println("Error: Activity class " +
intent.getComponent().toShortString()
+ " does not exist.");
break;
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
out.println(
"Error: Activity not started, you requested to "
+ "both forward and receive its result");
break;
case ActivityManager.START_PERMISSION_DENIED:
out.println(
"Error: Activity not started, you do not "
+ "have permission to access it.");
break;
case ActivityManager.START_NOT_VOICE_COMPATIBLE:
out.println(
"Error: Activity not started, voice control not allowed for: "
+ intent);
break;
case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
out.println(
"Error: Not allowed to start background user activity"
+ " that shouldn't be displayed for all users.");
break;
default:
out.println(
"Error: Activity not started, unknown error code " + res);
break;
}
out.flush();
//设置-W的情况下并且launched = true定位情况下,打印对应数据
if (mWaitOption && launched) {
if (result == null) {
result = new WaitResult();
result.who = intent.getComponent();
}
pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
if (result.who != null) {
pw.println("Activity: " + result.who.flattenToShortString());
}
if (result.thisTime >= 0) {
pw.println("ThisTime: " + result.thisTime);
}
if (result.totalTime >= 0) {
pw.println("TotalTime: " + result.totalTime);
}
pw.println("WaitTime: " + (endTime-startTime));
pw.println("Complete");
pw.flush();
}
mRepeat--;
if (mRepeat > 0) {
mInterface.unhandledBack();
}
}
} while (mRepeat > 0);