通过在线程中运行xposed在钩子方法中显示对话框

时间:2015-08-19 18:23:40

标签: android alertdialog xposed-framework

我尝试在带有xposed的钩子方法中显示AlertDialog。 问题是该方法在线程中运行,并且该线程在线程等中运行......

例如: 活动 - >线程 - >线程 - > ... - >功能

有没有办法显示我的AlertDialog?我有上下文,但由于钩子函数不在主线程中,所以没用。

编辑(部分代码):

public class Xposed implements IXposedHookLoadPackage {
private Context ctx;
private Queue<String> queue = new LinkedList<>();

public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
    if (!lpparam.packageName.equals("xxx.xxx.xxx")) {
        return;
    }

    // Here I get the context from the static class extending Application
    findAndHookMethod("xxx.xxx.xxx", lpparam.classLoader, "attachBaseContext", Context.class, new XC_MethodHook() {
        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            XposedBridge.log("context modified");
            ctx = (Context) param.args[0];
        }
    });

    findAndHookMethod("com.xxx.xxx.xxx", lpparam.classLoader, "e", "com.xxx.xxx.xxx", String.class, new XC_MethodHook() {
        @Override
        protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
            if (!(param.args[1]).equals("xxxxxxxxxxxxxx")) {
                return ;
            }

            XposedBridge.log("New element detected detected");
            Object param = param.args[0];
            Object info = callMethod(param, "q");

            // Here, I want to show my alertdialog
            DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (which == DialogInterface.BUTTON_POSITIVE) {

                    }
                }
            };

            // I get the classic error like what I can't modify the ui
            // in a thread that has not called Looper.prepare()
            AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
            builder.setMessage("Are you sure ?")
                    .setPositiveButton("Yes", dialogClickListener)
                    .setNegativeButton("No", dialogClickListener)
                    .show();
        }
    });
}

由于

3 个答案:

答案 0 :(得分:4)

您始终可以保留当前活动的参考(android.app.Instrumentation.newActivity)。它是这样的:

Class<?> instrumentation = XposedHelpers.findClass(
                "android.app.Instrumentation", lpparam.classLoader);

Method method = instrumentation.getMethod("newActivity",
                 ClassLoader.class, String.class, Intent.class);

XposedBridge.hookMethod(method, iHook);

在这种情况下,ihook将是你的一个钩子,它只是静态存储当前的Activity,所以你可以从任何地方调用runOnUiThread:

public class ActivityHook extends XC_MethodHook{

    /* Assure latest read of write */
    private static volatile Activity _currentActivity = null;

    public static Activity getCurrentActivity() {
        return _currentActivity;
    }

    @Override
    protected Object afterHookedMethod(MethodHookParam param)
            throws Throwable {
        _currentActivity = (Activity) param.getResult();
    }
}

然后你可以在任何地方做到:

ActivityHook.getCurrentActivity().runOnUiThread(...);
祝你好运!

答案 1 :(得分:1)

由于您无法访问某个活动,因此您可以获取主要活动,然后发布与ui相关的任务。

注意:当您需要在xposed模块中获取当前应用程序上下文时,您不需要挂钩attachBaseContext之类的内容。 xposed api提供了一种辅助方法,用于获取当前应用程序上下文AndroidAppHelper.currentApplication()

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        //Do ui related stuff in here
        AlertDialog.Builder builder = new AlertDialog.Builder(AndroidAppHelper.currentApplication());
        builder.setMessage("Are you sure ?")
                .setPositiveButton("Yes", dialogClickListener)
                .setNegativeButton("No", dialogClickListener)
                .show();
    }
});

Looper.getMainLooper()文档:http://developer.android.com/reference/android/os/Looper.html#getMainLooper()

Handler.post文档: http://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable)

AndroidAppHelper.currentApplication()源代码: https://github.com/rovo89/XposedBridge/blob/art/src/android/app/AndroidAppHelper.java#L143-L145

答案 2 :(得分:0)

如果您在活动或片段中运行此代码,则可以使用runOnUiThread(runnable)方法执行此操作。