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 了解不多,但这里有几个问题

  1. 您可以在运行时导入 class(在编译语言中)
  2. 您正在尝试做相当于 Reflection 的事情(但没有做任何事情)
  3. 安全。没有用户会同意您可以远程控制在他们的应用程序上打开屏幕

大概 BeanShell 应该在幕后进行反射,但在某些情况下您将无法进行导入。

可能的解决方案

  1. 使用库的 class/activity 应该导入所有内容(我不确定编译器是否会保留它)
  2. 你可以直接使用反射,比如"method from name"。缺点是除非您处理大量情况,否则您可以从服务器发送的代码非常有限。
  3. 您只能发送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,一切都很顺利!