BeanShell Android 问题。无法远程启动 activity
BeanShell Android Issue. Unable to start activity remotely
美好的一天。 BeanShell 最令人惊奇的事情是我可以控制我想从服务器动态完成的事情,我认为这会很棒。
尽管我从未成功实现这一目标,而且似乎也没有其他人尝试从 beanshell 开始 activity。
这是怎么回事。我只是想将代码从服务器端传递到 Android,Android 将在解释器中评估该代码,运行 那个。
问题是无论我尝试什么,我都从 BeanShell 得到异常。
服务器端的代码是下一个。
$response['method'] = "import my.some.name.*;"
. "startActivity(new Intent(this,MyProfile.class))";
Android 的代码是下一个。
try {
String responseBody = response.body().string();
JSONObject jsonObject = new JSONObject(responseBody);
String method = jsonObject.optString("method");
Interpreter interpreter = new Interpreter();
try {
Object res = interpreter.eval(method);
} catch (EvalError evalError) {
evalError.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
但是我从 BeanShell 得到了下一个异常
Sourced file: inline evaluation of: ``import my.some.name.*;startActivity(new Intent(this,MyProfile.class));'' : Class: MyProfile not found in namespace : at Line: 1 : in file: inline evaluation of: ``import my.some.name.*;startActivity(new Intent(this,MyProfile.class));'' : MyProfile
知道发生了什么事吗?
可能的问题
我对 BeanShell 了解不多,但这里有几个问题
- 您可以在运行时导入 class(在编译语言中)
- 您正在尝试做相当于 Reflection 的事情(但没有做任何事情)
- 安全。没有用户会同意您可以远程控制在他们的应用程序上打开屏幕
大概 BeanShell 应该在幕后进行反射,但在某些情况下您将无法进行导入。
可能的解决方案
- 使用库的 class/activity 应该导入所有内容(我不确定编译器是否会保留它)
- 你可以直接使用反射,比如"method from name"。缺点是除非您处理大量情况,否则您可以从服务器发送的代码非常有限。
您只能发送names/commands;到您 java 应用程序中的特定端点(这是我推荐的)并提前计划您想要的操作
$response['method'] = "my.some.name.MyProfile";
JSONObject jsonObject = new JSONObject(response.body().string());
String nameParam = jsonObject.optString("method");
Class<? extends Activity> clazz = Class.forName(nameParam); //wrap with try
startActivity( new Intent(this, clazz) )
为了以防万一,如果有人需要相同的解决方案,我发布给大家。
事情是这样的。
首先你需要知道无论你试图在服务器端做什么,请记住 BeanShell 实际上对你传递给自己的字符串代码一无所知,因为它将像代码一样解释它开箱即用,因此借助 CommonWare 关于全名路径的提示,我设法使其正常工作。
所以第一步是初始化解释器。
基本初始化是这样的:
String responseBody = response.body().string();
JSONObject jsonObject = new JSONObject(responseBody);
String method = jsonObject.optString("method");
Interpreter interpreter = new Interpreter();
try {
interpreter.set("context",getApplicationContext());
Object res = interpreter.eval(method);
} catch (EvalError evalError) {
evalError.printStackTrace();
}
请特别注意 context
,因为这是我反复讨论的主要问题,就在我成功强制 BeanShell 识别我的 classes 的那一刻,BeanShell 开始抛出关于 startActivity()
的 Method not found
异常,因此通过逻辑思考,我们可以假设我们将上下文设置为 activity 作为我们远程方法的父对象,并开始评估 context
。所以这里是远程代码的样子。
$response['method'] = "import ink.va.activities;"
. "import android.content.Intent;"
. "import android.content.*;"
. "context.startActivity(new android.content.Intent(context, my.package.name.MyProfile.class));";
这里要注意的最重要的事情。
• 我们正在导入所有可能的 BeanShell 以识别我们的 classes,即使它们是 Android-Build,无论如何,我们仍然需要导入它们。
• 如果您要使用任何 class,那么正如 CommonWare 注意到的那样,您必须指定 Class E.G my.package.name.MyProfile.class
.
的完整路径
• 当我得到 Command Not Found
时,我开始考虑 context.startActivity()
,因为我事先在 BeanShell 中将 context
定义为我的父级,我将从中使用方法还有 Woala,一切都很顺利!
美好的一天。 BeanShell 最令人惊奇的事情是我可以控制我想从服务器动态完成的事情,我认为这会很棒。
尽管我从未成功实现这一目标,而且似乎也没有其他人尝试从 beanshell 开始 activity。
这是怎么回事。我只是想将代码从服务器端传递到 Android,Android 将在解释器中评估该代码,运行 那个。
问题是无论我尝试什么,我都从 BeanShell 得到异常。
服务器端的代码是下一个。
$response['method'] = "import my.some.name.*;"
. "startActivity(new Intent(this,MyProfile.class))";
Android 的代码是下一个。
try {
String responseBody = response.body().string();
JSONObject jsonObject = new JSONObject(responseBody);
String method = jsonObject.optString("method");
Interpreter interpreter = new Interpreter();
try {
Object res = interpreter.eval(method);
} catch (EvalError evalError) {
evalError.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
但是我从 BeanShell 得到了下一个异常
Sourced file: inline evaluation of: ``import my.some.name.*;startActivity(new Intent(this,MyProfile.class));'' : Class: MyProfile not found in namespace : at Line: 1 : in file: inline evaluation of: ``import my.some.name.*;startActivity(new Intent(this,MyProfile.class));'' : MyProfile
知道发生了什么事吗?
可能的问题
我对 BeanShell 了解不多,但这里有几个问题
- 您可以在运行时导入 class(在编译语言中)
- 您正在尝试做相当于 Reflection 的事情(但没有做任何事情)
- 安全。没有用户会同意您可以远程控制在他们的应用程序上打开屏幕
大概 BeanShell 应该在幕后进行反射,但在某些情况下您将无法进行导入。
可能的解决方案
- 使用库的 class/activity 应该导入所有内容(我不确定编译器是否会保留它)
- 你可以直接使用反射,比如"method from name"。缺点是除非您处理大量情况,否则您可以从服务器发送的代码非常有限。
您只能发送names/commands;到您 java 应用程序中的特定端点(这是我推荐的)并提前计划您想要的操作
$response['method'] = "my.some.name.MyProfile"; JSONObject jsonObject = new JSONObject(response.body().string()); String nameParam = jsonObject.optString("method"); Class<? extends Activity> clazz = Class.forName(nameParam); //wrap with try startActivity( new Intent(this, clazz) )
为了以防万一,如果有人需要相同的解决方案,我发布给大家。
事情是这样的。
首先你需要知道无论你试图在服务器端做什么,请记住 BeanShell 实际上对你传递给自己的字符串代码一无所知,因为它将像代码一样解释它开箱即用,因此借助 CommonWare 关于全名路径的提示,我设法使其正常工作。
所以第一步是初始化解释器。
基本初始化是这样的:
String responseBody = response.body().string();
JSONObject jsonObject = new JSONObject(responseBody);
String method = jsonObject.optString("method");
Interpreter interpreter = new Interpreter();
try {
interpreter.set("context",getApplicationContext());
Object res = interpreter.eval(method);
} catch (EvalError evalError) {
evalError.printStackTrace();
}
请特别注意 context
,因为这是我反复讨论的主要问题,就在我成功强制 BeanShell 识别我的 classes 的那一刻,BeanShell 开始抛出关于 startActivity()
的 Method not found
异常,因此通过逻辑思考,我们可以假设我们将上下文设置为 activity 作为我们远程方法的父对象,并开始评估 context
。所以这里是远程代码的样子。
$response['method'] = "import ink.va.activities;"
. "import android.content.Intent;"
. "import android.content.*;"
. "context.startActivity(new android.content.Intent(context, my.package.name.MyProfile.class));";
这里要注意的最重要的事情。
• 我们正在导入所有可能的 BeanShell 以识别我们的 classes,即使它们是 Android-Build,无论如何,我们仍然需要导入它们。
• 如果您要使用任何 class,那么正如 CommonWare 注意到的那样,您必须指定 Class E.G my.package.name.MyProfile.class
.
• 当我得到 Command Not Found
时,我开始考虑 context.startActivity()
,因为我事先在 BeanShell 中将 context
定义为我的父级,我将从中使用方法还有 Woala,一切都很顺利!