Java 反射-ClassNotFoundException

Java 反射-ClassNotFoundException,java,android,reflection,Java,Android,Reflection,我正试图找到一种方法,以编程方式和干净的方式关闭设备。我的应用程序具有根/系统权限,因此我不想使用建议的方法来执行此操作,而是希望像系统那样“正确地”执行此操作 使用反射,我试图访问类以及其中的shutdown方法 private static final String SHUTDOWN_CLASS = "com.android.internal.app.ShutdownThread"; private static final String SHUTDOWN_METHOD = "shutdow

我正试图找到一种方法,以编程方式和干净的方式关闭设备。我的应用程序具有根/系统权限,因此我不想使用建议的方法来执行此操作,而是希望像系统那样“正确地”执行此操作

使用反射,我试图访问类以及其中的shutdown方法

private static final String SHUTDOWN_CLASS = "com.android.internal.app.ShutdownThread";
private static final String SHUTDOWN_METHOD = "shutdown";

Class<?> sdClass;
Method shutdown;
boolean sd;
boolean success = false;

try {
    sdClass = Class.forName(SHUTDOWN_CLASS);
    Object obj = sdClass.newInstance();

    shutdown = sdClass.getDeclaredMethod(SHUTDOWN_METHOD);

    shutdown.setAccessible(true);
    sd = (Boolean) shutdown.invoke(obj, ctx, false);

    success = sd;

} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
}
我使用的操作字符串要么为null,要么为bootloader,要么为recovery。我满怀希望地尝试“关机”,但没有成功。这些显然是发送到内核的消息,但我找不到在任何地方都可用的引用

注意:在您发布“您不应该以编程方式执行此操作”之前,我的用户已经请求了它,并且完全了解我的应用程序具有的系统和根权限。这就是他们安装它的原因

如果有人能指出我所做的是不可能的,或者我第一次尝试使用反射时哪里出了问题,我会很感激的


更新 Commonware的评论当然是绝对正确的,类路径不再存在。在Jelly Bean源代码中,它现在是

我已经尽了我所能,但是使用下面的代码无法解决坏窗口令牌的问题

boolean sd = false;
boolean success = false;

        try {
            Class<?> sdClass = Class.forName("com.android.server.power.ShutdownThread");

            for (Constructor<?> ctor : sdClass.getDeclaredConstructors()) {
                // Log output
            }

            Constructor<?> con = sdClass.getDeclaredConstructors()[0];
            con.setAccessible(true);

            for (Method m : sdClass.getDeclaredMethods()) {

                if (m.getName().matches("shutdown")) {
                    m.setAccessible(true);
                    sd = (Boolean) m.invoke(ctx, ctx, false);
                }
            }

            success = sd;

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
             e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
             e.printStackTrace();
        }

        return success;
布尔sd=false;
布尔成功=假;
试一试{
Class sdClass=Class.forName(“com.android.server.power.ShutdownThread”);
对于(构造函数构造函数:sdClass.getDeclaredConstructors()){
//日志输出
}
构造函数con=sdClass.getDeclaredConstructors()[0];
con.setAccessible(true);
对于(方法m:sdClass.getDeclaredMethods()){
如果(m.getName().matches(“shutdown”)){
m、 setAccessible(true);
sd=(布尔)m.invoke(ctx,ctx,false);
}
}
成功=标准差;
}catch(classnotfounde异常){
e、 printStackTrace();
}捕获(无此方法例外){
e、 printStackTrace();
}捕获(IllegalArgumentException e){
e、 printStackTrace();
}捕获(非法访问例外e){
e、 printStackTrace();
}捕获(调用TargetException e){
e、 printStackTrace();
}捕获(实例化异常e){
e、 printStackTrace();
}
回归成功;
我现在得到的错误是:

W/系统错误(17002):由以下原因引起: android.view.WindowManager$BadTokenException:无法添加窗口 android.view.ViewRootImpl$W@41ae4a10--拒绝对此进行许可 窗口类型

带系统错误(17002):在 com.android.server.power.ShutdownThread.beginShutdownSequence(ShutdownThread.java:222)


我假设这是因为我是从服务执行的,而它可能需要从前台活动执行?如果有人有任何线索,我很想知道……

不,你“不应该以编程方式这样做”,因为未记录的机制会随着时间的推移而变化。例如,现代版本的android.Ha中没有
com.android.internal.app.ShutdownThread
!我没什么可说的了@brandall我也面临同样的问题,得到ans了吗?@SIGSEGV我恐怕没有-这是我所能得到的
boolean sd = false;
boolean success = false;

        try {
            Class<?> sdClass = Class.forName("com.android.server.power.ShutdownThread");

            for (Constructor<?> ctor : sdClass.getDeclaredConstructors()) {
                // Log output
            }

            Constructor<?> con = sdClass.getDeclaredConstructors()[0];
            con.setAccessible(true);

            for (Method m : sdClass.getDeclaredMethods()) {

                if (m.getName().matches("shutdown")) {
                    m.setAccessible(true);
                    sd = (Boolean) m.invoke(ctx, ctx, false);
                }
            }

            success = sd;

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
             e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
             e.printStackTrace();
        }

        return success;