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

时间:2015-06-14 07:51:00

标签: android android-service

在我的应用程序中,我有本地服务,需要在单独的进程中运行。它被指定为

<service android:name=".MyService" android:process=":myservice"></service>
AndroidManifest.xml中的

。我也是Application对象的子类,并希望在普通启动和myservice启动时调用它的onCreate方法。我找到的唯一可行解决方案由

描述

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

但我不想在设备上获取所有正在运行的进程并迭代它们。我尝试使用来自Context的getApplicationInfo()。processName,但不幸的是它总是返回相同的String,而上面链接中的解决方案返回:myPackage,myPackage:myservice。我首先不需要processName,但是确定何时通过普通启动和myservice启动调用onCreate方法的一些好方法。也许可以通过在某处应用某种标签或标签来完成,但我还没有找到如何做到这一点。

3 个答案:

答案 0 :(得分:2)

您可以使用此代码获取您的进程名称:

    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
            }
        }
    }

答案 1 :(得分:1)

来自Acra来源。与上述答案相同,但提出了有用的方法

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.
    }
}

答案 2 :(得分:0)

您可以使用下一种方法

@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;
}