2012年11月19日 星期一

Extending monkeyrunner with Plugins - Jar File


Preface
As you can see the description on Android Developer Site, you can extend MonkeyRunner by writing  java programming language and integrate to an Jar file and create more capacities for your control purpose. In following section, using 21 steps to guide you how to create a monkeyrunner extension JAR file.

How to create a Jar component for MonkeyRunner?

Before we start to know how to create a Jar Component for MonkeyRunner, there're something you need to do in advance. The J2SDK installation on your computer is required and you need to know how to program  Java based program. Eclipse is an option, however it's very useful. Android SDK installation is required. 

Here I'll show you an example by using Eclipse to create a Jar component for MonkeyRunner Extension.

1. Using Eclipse to create a Java Project through File->New->Java Project. Fill the project name.
2. Press Next button.



 3. Tap Libraries.



4. Tap "Add External JARs..." button.



5. Add Jar files - Pick chimpchat.jar, guavalib.jar, jython.jar, and monkeyrunner.jar in the folder - /android_sdk_folder/tools/lib/.
6. Press Finish button.



7. Fill the package name - com.android.monkeyrunner.
8. Fill the class name.
9. Press Finish button.  



10.  If you need to initial some variable for monkeyrunner runtime environment, you can implement a interface named Predicate and write the initial thing in apply method.
11. In this example, I create three static methods for interacting with Android device. They're tap, PressButton, and saveScreenToFile respectively. These functions are to trigger a touch event, and a button event, and to save run-time screen to a file. In order to implement these function to communicate with Android device, we need to import MonkyDevice and MonkeyImage classes. The usage is similar with what you wrote on monkeyrunner console to control Android devices. The difference is that you need to use Python Object class for given parameters. For instance, to invoke a touch event, you can use touch method in MonkeyDevice class. But you need to give a value which is belong to the type of PyObject. Hence, we declare a PyObject variable and assign two integer and one string as their values that is needed by declared PyObject variable. For given parameters, the two integer values are used to assign where to touch and the string value is used to assign which action we're going to use for touch event (E.g. DOWN, UP, or DOWN_AND_UP). Note that, you can not use int as integer's type in PyObject's initialization. To assign an integer value to PyObject class, the type of PyInteger Object is needed. To assign a string value to PyObject class, the type of PyString Object is needed. 



12. The Eclipse is very useful for developing MonkeyRunner Extension Jar file, because you can see the tip when your mouse move cursor to the method. Hence, you can know what type and  you should use and how many parameters you should provide for particular method.

13. Start to export your wrote files to a Jar file for MonkeyRunner after you finish the coding work.
14. Move mouse to project name on Eclipse and right click the mouse.
15. Click Export option.  


16. Select JAR file and press Next button.



 17. Select the files which are going to be exported and press Next button.



18. Press Next Button.



19. If you don't have a MANIFEST file existed already, you can select option of "Generate the manifest file" and press Browser button to select where to store the MANIFEST file. You can give a name like MANIFEST.MF and place in root folder of project. If you have a MANIFEST file already, you can select option - Use existing manifest from workspace and select your own file.
20. Press Finish button.



21. Edit the MANIFEST file you used at last step and add a command - MonkeyRunnerStartupRunner: com.android.monkeyrunner.monkeyrunnerExt 
to MANIFEST file. The string of MonkeyRunnerStartupRunner: is followed by full package name of your class. Finally, save your modified MANIFEST file to your JAR file.


How to import your own Jar file for MonkeyRunner?

Copy your Jar file to /android-sdk_folder/tools/lib before running monkeyrunner.bat. Double click monkeyrunner.bat at the folder of android-sdk/tools/ to bring up a MonkeyRunner console as follows. And import the necessary class and your own class as follows. Then you can use your own class to do something on MonkeyRunner run-time environment.




Reference
http://developer.android.com/tools/help/monkeyrunner_concepts.html#Plugins

11 則留言:

  1. Sir, I am having problems with the last part of your (well described) process, the problem is that monkeyrunner refuses to import monkeyrunnerExt saying this package is not signed.
    tried repeating this process building it as Android app, but i couldn't find the way to create a Jar file and signing it.
    Hope u can help.
    Best Regards
    Raul Jacinto

    回覆刪除
  2. Greeting, do you follow all the steps aforementioned and have the same class name - monkeyrunnerExt with package name com.android.monkeyrunner? To sign this class is unnecessary.It's a Java application rather than a Android app. You should create a Jar file and don't need to sign it. The monkeyrunner plugin would be run with Monkeyrunner environment on a PC or NB. Is it helpful. Any question you can post here again. Good Luck.

    回覆刪除
  3. Thx for your demo about it.
    So when i'm import my class, it was show more problem:
    >monkeyrunner.bat -plugin MonKeyRunnerExt_001.jar

    >>> from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
    >>> from com.duy.monkeyrunner import monkeyrunnerExt as ME
    Traceback (most recent call last):
    File "", line 1, in
    ImportError: No module named duy

    MF file info:
    Manifest-Version: 1.0
    monkeyrunner: com.duy.monkeyrunner.monkeyrunnerExt

    Or:
    >>> from com.android.monkeyrunner import monkeyrunnerExt as ME
    Traceback (most recent call last):
    File "", line 1, in
    ImportError: cannot import name monkeyrunnerExt

    MF file info:
    Manifest-Version: 1.0
    monkeyrunner: com.android.monkeyrunner.monkeyrunnerExt

    Mypackage
    -----
    *.jar/com/android/monkeyrunner/monkeyrunnerExt.class
    ----

    My code:
    ----
    package com.android.monkeyrunner;

    import org.python.core.PyInteger;
    import org.python.core.PyObject;
    import org.python.core.PyString;
    import org.python.util.PythonInterpreter;
    import com.android.monkeyrunner.MonkeyDevice;
    import com.android.monkeyrunner.MonkeyImage;
    import com.google.common.base.Predicate;
    //import javax.sql.rowset.Predicate;

    public class monkeyrunnerExt implements Predicate{
    public static void tap(MonkeyDevice device, int x, int y){
    PyObject[] args = {
    new PyInteger(x),
    new PyInteger(y),
    new PyString("DOWN_AND_UP")
    };
    String[] str = null;
    device.touch(args, str);
    }

    public static void PressButton(MonkeyDevice device, String keyCode){
    PyObject[] args = {
    new PyString(keyCode),
    new PyString("DOWN_AND_UP"),
    new PyString("")
    };
    device.press(args, null);
    }

    public static void saveScreenToFile(MonkeyDevice device, String fileName){
    MonkeyImage snapShot = device.takeSnapshot();
    PyObject[] obj = {
    new PyString(fileName),
    new PyString("png")
    };
    String[] str = null;
    snapShot.writeToFile(obj, str);
    }

    @Override
    public boolean apply(PythonInterpreter arg0) {
    // TODO Auto-generated method stub
    return false;
    }

    }
    ----

    Plz help me look this :)
    --
    thx you

    回覆刪除
  4. Did you copy the jar file to yourSDKpath/tools/lib/?

    回覆刪除
  5. 您好,最近在研究monkeyrunner來到您的blog,感覺受益良多,謝謝
    我照著以上的步驟去執行,在最後也產生了MonkeyRunnerExt.jar
    可是在執行com.android.monkeyrunner import monkeyrunnerExt時出現錯誤:

    Traceback (most recent call last):
    File "", line 1, in
    java.lang.SecurityException: sealing violation: can't seal package com.android.monkeyrunner: already loaded
    ...
    ..
    java.lang.SecurityException: java.lang.SecurityException: sealing violation: can't seal package com.android.monkeyrunner: already loaded

    想跟您請教怎麼解決這個問題,謝謝

    回覆刪除
    回覆
    1. 您好,問題已經解決了
      真是不好意思,謝謝^^

      刪除
    2. 很快就能解決了, 很厲害喔.

      刪除
    3. How did you solve is the issue:

      Traceback (most recent call last):
      File "", line 1, in
      java.lang.SecurityException: sealing violation: can't seal package com.android.monkeyrunner: already loaded
      ...
      ..
      java.lang.SecurityException: java.lang.SecurityException: sealing violation: can't seal package com.android.monkeyrunner: already loaded

      刪除
    4. There is a problem with:

      package com.android.monkeyrunner

      it should be named something different, e.g.:

      package com.my.test.monkeyhelper

      that solves the issue

      刪除