简体   繁体   English

确定调用Application.onCreate()的进程

[英]Determine by which process Application.onCreate() is called

In my application I have local service, which needs to be run in separate process. 在我的应用程序中,我有本地服务,需要在单独的进程中运行。 It is specified as 它被指定为

<service android:name=".MyService" android:process=":myservice"></service>

in AndroidManifest.xml. 在AndroidManifest.xml中。 I also subclass Application object and want to detect in it's onCreate method when it is called by ordinary launch and when by myservice launch. 我也是Application对象的子类,并希望在普通启动和myservice启动时调用它的onCreate方法。 The only working solution that I have found is described by 我找到的唯一可行的解​​决方案是由

https://stackoverflow.com/a/28907058/2289482 https://stackoverflow.com/a/28907058/2289482

But I don't want to get all running processes on device and iterate over them. 但我不希望在设备上获取所有正在运行的进程并迭代它们。 I try to use getApplicationInfo().processName from Context, but unfortunately it always return the same String, while the solution in the link above return: myPackage, myPackage:myservice. 我尝试使用来自Context的getApplicationInfo()。processName,但不幸的是它总是返回相同的String,而上面链接中的解决方案返回:myPackage,myPackage:myservice。 I don't need processName at the first place, but some good solution to determine when onCreate method is called by ordinary launch and when by myservice launch. 我首先不需要processName,但是确定何时通过普通启动和myservice启动调用onCreate方法的一些好方法。 May be it can be done by applying some kind of tag or label somewhere, but i didn't find how to do it. 也许可以通过在某处应用某种标签或标签来完成,但我没有找到如何做到这一点。

You can use this code to get your process name: 您可以使用此代码获取进程名称:

    int myPid = android.os.Process.myPid(); // Get my Process ID
    InputStreamReader reader = null;
    try {
        reader = new InputStreamReader(
                new FileInputStream("/proc/" + myPid + "/cmdline"));
        StringBuilder processName = new StringBuilder();
        int c;
        while ((c = reader.read()) > 0) {
            processName.append((char) c);
        }
        // processName.toString() is my process name!
        Log.v("XXX", "My process name is: " + processName.toString());
    } catch (Exception e) {
        // ignore
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (Exception e) {
                // Ignore
            }
        }
    }

From Acra sources. 来自Acra的消息来源。 The same way as above answer but presents useful methods 与上述答案相同,但提出了有用的方法

private static final String ACRA_PRIVATE_PROCESS_NAME= ":acra";

/**
 * @return true if the current process is the process running the SenderService.
 *          NB this assumes that your SenderService is configured to used the default ':acra' process.
 */
public static boolean isACRASenderServiceProcess() {
    final String processName = getCurrentProcessName();
    if (ACRA.DEV_LOGGING) log.d(LOG_TAG, "ACRA processName='" + processName + '\'');
    //processName sometimes (or always?) starts with the package name, so we use endsWith instead of equals
    return processName != null && processName.endsWith(ACRA_PRIVATE_PROCESS_NAME);
}

@Nullable
private static String getCurrentProcessName() {
    try {
        return IOUtils.streamToString(new FileInputStream("/proc/self/cmdline")).trim();
    } catch (IOException e) {
        return null;
    }
}

private static final Predicate<String> DEFAULT_FILTER = new Predicate<String>() {
    @Override
    public boolean apply(String s) {
        return true;
    }
};
private static final int NO_LIMIT = -1;

public static final int DEFAULT_BUFFER_SIZE_IN_BYTES = 8192;

/**
 * Reads an InputStream into a string
 *
 * @param input  InputStream to read.
 * @return the String that was read.
 * @throws IOException if the InputStream could not be read.
 */
@NonNull
public static String streamToString(@NonNull InputStream input) throws IOException {
    return streamToString(input, DEFAULT_FILTER, NO_LIMIT);
}

/**
 * Reads an InputStream into a string
 *
 * @param input  InputStream to read.
 * @param filter Predicate that should return false for lines which should be excluded.
 * @param limit the maximum number of lines to read (the last x lines are kept)
 * @return the String that was read.
 * @throws IOException if the InputStream could not be read.
 */
@NonNull
public static String streamToString(@NonNull InputStream input, Predicate<String> filter, int limit) throws IOException {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(input), ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES);
    try {
        String line;
        final List<String> buffer = limit == NO_LIMIT ? new LinkedList<String>() : new BoundedLinkedList<String>(limit);
        while ((line = reader.readLine()) != null) {
            if (filter.apply(line)) {
                buffer.add(line);
            }
        }
        return TextUtils.join("\n", buffer);
    } finally {
        safeClose(reader);
    }
}

/**
 * Closes a Closeable.
 *
 * @param closeable Closeable to close. If closeable is null then method just returns.
 */
public static void safeClose(@Nullable Closeable closeable) {
    if (closeable == null) return;

    try {
        closeable.close();
    } catch (IOException ignored) {
        // We made out best effort to release this resource. Nothing more we can do.
    }
}

You can use the next method 您可以使用下一个方法

@Nullable
public static String getProcessName(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningAppProcessInfo processInfo : activityManager.getRunningAppProcesses()) {
        if (processInfo.pid == android.os.Process.myPid()) {
            return processInfo.processName;
        }
    }
    return null;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Application.onCreate被多次调用 - Application.onCreate called more than once Application.onCreate() 未在调试版本中调用 - Application.onCreate() not called in debug build 在Application.onCreate代码之前调用NotificationListenerService - NotificationListenerService called before Application.onCreate code Android Application.onCreate漫长的过程 - Android Application.onCreate long process Android Activity::onCreate 在 Application.onCreate 之前调用 - Android Activity::onCreate called before Application.onCreate 在Application.onCreate()上的BroadcastReceiver - BroadcastReceiver on Application.onCreate() 在BroadcastReceiver.onReceive(..)之前是否会调用Application.onCreate(Bundle)? - Will Application.onCreate(Bundle) be called before BroadcastReceiver.onReceive(..)? 是否有Android注释要求在Application.onCreate期间调用方法? - Is there an Android annotation to require that a method be called during Application.onCreate? 为什么 ContentProvider.onCreate() 在 Application.onCreate() 之前被调用? - Why does ContentProvider.onCreate() get called before Application.onCreate()? 如果应用程序闲置了数小时并被OS破坏,是否在Activity.onResume之前调用Application.onCreate? - Is Application.onCreate called before Activity.onResume if app has been idle for hours and destroyed by OS?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM