Search code examples
androidbeanshell

BeanShell Android Issue. Unable to start activity remotely


Good day. The main amazing thing about the BeanShell is the idea that i can control what i want to be done dynamically from the server and i thought it would be amazing.

Although i never succeded in achieving that and seems no one else tried to start activity from the beanshell either.

Here how it goes. I simply want to pass the code from the server side to the Android,Android is going to evaluate that code within interpreter and run that.

The issue is that i am getting the exception from BeanShell no matter what i try.

The code from server side is the next.

   $response['method'] = "import my.some.name.*;"
        . "startActivity(new Intent(this,MyProfile.class))";

The code for Android is the next.

  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();
            }
        }

But i am getting the next exception from the 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 

Any ideas what is going on?


Solution

  • Just in case if anyone needs the same solution i am posting for everyone to know.

    Here how it goes.

    Firstly you need to know that whatever you are trying to do on the server side remember that the BeanShell actually does not know anything about the String code you are passing itself,as it is going to interpret it just like a code out of box so with the help of CommonWare hint about full name path i managed to get it working.

    So first step to do is to initialize the Interpreter.

    Basic initialization goes like this :

      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();
                    }
    

    Take a very attentive notice about the context as it was my main issue going back and forth as at the moment when i succeded to actually force BeanShell recognize my classes,the BeanShell started to throw Method not found exception about the startActivity() so by thinking logically we can assume that we would set the context as activity as the parent one for our remote methods and start evaluating everything from the context. So here how the remote code is looking.

    $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));";
    

    The most important things to notice here.

    • We are importing everything possible for BeanSherll to recognize our classes,even if they are Android-Build,no matter,still we need to import them.

    • If you are going to use any class,then as CommonWare noticed out,you MUST specify the full path to that Class E.G my.package.name.MyProfile.class.

    • As i was getting Command Not Found i started to think about the context.startActivity() as i have defined the context beforehand in BeanShell as my parent from which i am going to use methods and Woala,everything worked like a charm!