我尝试在带有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();
}
});
}
由于
答案 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)
方法执行此操作。