Is there a way to get current process name in Android

后端 未结 11 1749
-上瘾入骨i
-上瘾入骨i 2020-12-03 00:59

I set an Android:process=\":XX\" for my particular activity to make it run in a separate process. However when the new activity/process init, it will call my Application:onC

相关标签:
11条回答
  • 2020-12-03 01:28

    First, get the current process pid. Second, list all processes of running. Finally, if it has equal pid, it's ok, or it's false.

    public static String getProcessName(Context context) {
        int pid = android.os.Process.myPid();
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
        if (infos != null) {
            for (ActivityManager.RunningAppProcessInfo processInfo : infos) {
                if (processInfo.pid == pid) {
                    return processInfo.processName;
                }
            }
        }
        return null;
    }
    
    0 讨论(0)
  • 2020-12-03 01:32

    Since Android Pie (SDK v28), there is actually an official method for this in the Application class:

    public static String getProcessName ()

    See the docs

    0 讨论(0)
  • 2020-12-03 01:34

    Get it from ActivityThread

    In API 28+, you can call Application.getProcessName(), which is just a public wrapper around ActivityThread.currentProcessName().

    On older platforms, just call ActivityThread.currentProcessName() directly.

    Note that prior to API 18, the method was incorrectly called ActivityThread.currentPackageName() but still in fact returned the process name.

    Example code

    public static String getProcessName() {
        if (Build.VERSION.SDK_INT >= 28)
            return Application.getProcessName();
    
        // Using the same technique as Application.getProcessName() for older devices
        // Using reflection since ActivityThread is an internal API
    
        try {
            @SuppressLint("PrivateApi")
            Class<?> activityThread = Class.forName("android.app.ActivityThread");
    
            // Before API 18, the method was incorrectly named "currentPackageName", but it still returned the process name
            // See https://github.com/aosp-mirror/platform_frameworks_base/commit/b57a50bd16ce25db441da5c1b63d48721bb90687
            String methodName = Build.VERSION.SDK_INT >= 18 ? "currentProcessName" : "currentPackageName";
    
            Method getProcessName = activityThread.getDeclaredMethod(methodName);
            return (String) getProcessName.invoke(null);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
    

    Compatibility

    Tested and working on

    • Official emulator
      • 16
      • 17
      • 18
      • 19
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • Q beta 1
    • Real devices
      • Motorola Moto G5 Plus running Android 8.1.0
      • Samsung Galaxy S5 running Android 6.0.1
      • Sony Xperia M running stock Android 7.1.1
      • Sony Xperia M running Sony Android 4.1.2
    0 讨论(0)
  • 2020-12-03 01:34

    To wrap up different approaches of getting process name using Kotlin:

    Based on the https://stackoverflow.com/a/21389402/3256989 (/proc/pid/cmdline):

        fun getProcessName(): String? =
            try {
                FileInputStream("/proc/${Process.myPid()}/cmdline")
                    .buffered()
                    .readBytes()
                    .filter { it > 0 }
                    .toByteArray()
                    .inputStream()
                    .reader(Charsets.ISO_8859_1)
                    .use { it.readText() }
            } catch (e: Throwable) {
                null
            }
    
    

    Based on https://stackoverflow.com/a/55549556/3256989 (from SDK v.28 (Android P)):

      fun getProcessName(): String? = 
        if (VERSION.SDK_INT >= VERSION_CODES.P) Application.getProcessName() else null
    

    Based on https://stackoverflow.com/a/45960344/3256989 (reflection):

        fun getProcessName(): String? =
            try {
                val loadedApkField = application.javaClass.getField("mLoadedApk")
                loadedApkField.isAccessible = true
                val loadedApk = loadedApkField.get(application)
    
                val activityThreadField = loadedApk.javaClass.getDeclaredField("mActivityThread")
                activityThreadField.isAccessible = true
                val activityThread = activityThreadField.get(loadedApk)
    
                val getProcessName = activityThread.javaClass.getDeclaredMethod("getProcessName")
                getProcessName.invoke(activityThread) as String
            } catch (e: Throwable) {
                null
            }
    

    Based on https://stackoverflow.com/a/19632382/3256989 (ActivityManager):

        fun getProcessName(): String? {
            val pid = Process.myPid()
            val manager = appContext.getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager
            return manager?.runningAppProcesses?.filterNotNull()?.firstOrNull { it.pid == pid }?.processName
        }
    
    0 讨论(0)
  • 2020-12-03 01:35

    The main process's father process should be zygote, this should be the accurate solution

    1. first judge the process's name from /proc/pid/cmdline which should equal to package name
    2. judge the process's father whether Zygote(why do this? because some APP have different processes with same name)
    0 讨论(0)
提交回复
热议问题