在 Android 上嵌入 Rhino 的问题
当尝试在 Android 2.2 上使用 Rhino 1.7 r2 将对象添加到 JS 环境时,我总是收到 NullPointerException。我已将课程精简到最低限度以获得此异常,但我不明白为什么。这是总是产生异常的代码:
public class StartActivity extends Activity
{
/** Rhino context object */
private Context mCX;
/** Rhino script scope object */
private Scriptable mScope;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create our context and turn off compilation
mCX = Context.enter();
mCX.setOptimizationLevel( -1 );
// Initialize the scope
mScope = mCX.initStandardObjects();
Object insertObj;
// This line always throws the exception.
insertObj = Context.javaToJS( this, mScope );
// We never get here
ScriptableObject.putProperty( mScope, "platform", insertObj );
setContentView(R.layout.main);
}
}
将麻烦的行更改为其他行,例如 insertObj = Context.javaToJS( null, mScope ); 或除 this
之外的任何内容和问题不会发生。
这是堆栈跟踪:
E/AndroidRuntime( 308): FATAL EXCEPTION: main
E/AndroidRuntime( 308): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.me/com.me.StartActivity}: java.lang.NullPointerException
E/AndroidRuntime( 308): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
E/AndroidRuntime( 308): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
E/AndroidRuntime( 308): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
E/AndroidRuntime( 308): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
E/AndroidRuntime( 308): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 308): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 308): at android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime( 308): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 308): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 308): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
E/AndroidRuntime( 308): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
E/AndroidRuntime( 308): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 308): Caused by: java.lang.NullPointerException
E/AndroidRuntime( 308): at org.mozilla.javascript.net.sf.retrotranslator.runtime.impl.MethodDescriptor.getInstance(MethodDescriptor.java:137)
E/AndroidRuntime( 308): at org.mozilla.javascript.net.sf.retrotranslator.runtime.java.lang.reflect._Constructor.isVarArgs(_Constructor.java:83)
E/AndroidRuntime( 308): at org.mozilla.javascript.jdk15.VMBridge_jdk15.isVarArgs(VMBridge_jdk15.java:66)
E/AndroidRuntime( 308): at org.mozilla.javascript.MemberBox.init(MemberBox.java:86)
E/AndroidRuntime( 308): at org.mozilla.javascript.MemberBox.<init>(MemberBox.java:72)
E/AndroidRuntime( 308): at org.mozilla.javascript.JavaMembers.reflect(JavaMembers.java:667)
E/AndroidRuntime( 308): at org.mozilla.javascript.JavaMembers.<init>(JavaMembers.java:76)
E/AndroidRuntime( 308): at org.mozilla.javascript.JavaMembers.lookupClass(JavaMembers.java:838)
E/AndroidRuntime( 308): at org.mozilla.javascript.NativeJavaObject.initMembers(NativeJavaObject.java:90)
E/AndroidRuntime( 308): at org.mozilla.javascript.NativeJavaObject.<init>(NativeJavaObject.java:80)
E/AndroidRuntime( 308): at org.mozilla.javascript.NativeJavaObject.<init>(NativeJavaObject.java:70)
E/AndroidRuntime( 308): at org.mozilla.javascript.WrapFactory.wrapAsJavaObject(WrapFactory.java:149)
E/AndroidRuntime( 308): at org.mozilla.javascript.WrapFactory.wrap(WrapFactory.java:105)
E/AndroidRuntime( 308): at org.mozilla.javascript.Context.javaToJS(Context.java:1698)
E/AndroidRuntime( 308): at com.me.android.StartActivity.onCreate(StartActivity.java:34)
E/AndroidRuntime( 308): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime( 308): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
E/AndroidRuntime( 308): ... 11 more
任何有关为什么会发生这种情况的见解都将不胜感激。
[编辑] 经过一番认真的谷歌搜索和头脑风暴后,我发现了 ScriptableObject.defineClass
方法,并尝试按照 Rhino 文档中的示例使用它,但是现在我得到了一个RuntimeException“ReferenceError:未定义‘DeviceInterface’。”我知道这是可能的,因为 ASE 使用 Rhino 来支持 JavaScript。
的新代码:
public class StartActivity extends Activity
{
/** Rhino context object */
private Context mCX;
/** Rhino script scope object */
private Scriptable mScope;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create our context and turn off compilation
mCX = Context.enter();
mCX.setOptimizationLevel( -1 );
// Initialize the scope
mScope = mCX.initStandardObjects();
try{
ScriptableObject.defineClass( mScope, DeviceInterface.class );
} catch( Exception e ) {
Log.e("StartActivity", e.toString());
}
// This is the line that throws the exception
mCX.evaluateString(mScope,
"var p = new DeviceInterface();", "",
1, null);
setContentView(R.layout.main);
}
}
这是抛出 RuntimeException:和 DeviceInterface 类
public class DeviceInterface extends ScriptableObject
{
static private final long serialVersionUID = 1L;
static public void init ( Scriptable scope )
{
Log.i( "JSInterface", "Init called" );
}
public DeviceInterface()
{
logger( "Created new JSInterface Object" );
}
@Override
public String getClassName()
{
return "DeviceInterface";
}
public void jsFunction_logger( String message )
{
logger( message );
}
private void logger( String message )
{
if( message.contains("[alrt]") )
Log.e( "JSInterface", message );
else if( message.contains("[info]") )
Log.i( "JSInterface", message );
else
Log.d( "JSInterface", message );
}
}
When trying to add an object to the JS environment using Rhino 1.7 r2 on Android 2.2 I always get a NullPointerException. I have boiled the class down to the bare minimum to get this exception, and I can't figure out why. Here's the code that always produces the exception:
public class StartActivity extends Activity
{
/** Rhino context object */
private Context mCX;
/** Rhino script scope object */
private Scriptable mScope;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create our context and turn off compilation
mCX = Context.enter();
mCX.setOptimizationLevel( -1 );
// Initialize the scope
mScope = mCX.initStandardObjects();
Object insertObj;
// This line always throws the exception.
insertObj = Context.javaToJS( this, mScope );
// We never get here
ScriptableObject.putProperty( mScope, "platform", insertObj );
setContentView(R.layout.main);
}
}
Changing the troublesome line to some else like insertObj = Context.javaToJS( null, mScope );
or really anything but this
and the problem doesn't occur.
Here is the stacktrace:
E/AndroidRuntime( 308): FATAL EXCEPTION: main
E/AndroidRuntime( 308): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.me/com.me.StartActivity}: java.lang.NullPointerException
E/AndroidRuntime( 308): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
E/AndroidRuntime( 308): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
E/AndroidRuntime( 308): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
E/AndroidRuntime( 308): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
E/AndroidRuntime( 308): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 308): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 308): at android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime( 308): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 308): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 308): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
E/AndroidRuntime( 308): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
E/AndroidRuntime( 308): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 308): Caused by: java.lang.NullPointerException
E/AndroidRuntime( 308): at org.mozilla.javascript.net.sf.retrotranslator.runtime.impl.MethodDescriptor.getInstance(MethodDescriptor.java:137)
E/AndroidRuntime( 308): at org.mozilla.javascript.net.sf.retrotranslator.runtime.java.lang.reflect._Constructor.isVarArgs(_Constructor.java:83)
E/AndroidRuntime( 308): at org.mozilla.javascript.jdk15.VMBridge_jdk15.isVarArgs(VMBridge_jdk15.java:66)
E/AndroidRuntime( 308): at org.mozilla.javascript.MemberBox.init(MemberBox.java:86)
E/AndroidRuntime( 308): at org.mozilla.javascript.MemberBox.<init>(MemberBox.java:72)
E/AndroidRuntime( 308): at org.mozilla.javascript.JavaMembers.reflect(JavaMembers.java:667)
E/AndroidRuntime( 308): at org.mozilla.javascript.JavaMembers.<init>(JavaMembers.java:76)
E/AndroidRuntime( 308): at org.mozilla.javascript.JavaMembers.lookupClass(JavaMembers.java:838)
E/AndroidRuntime( 308): at org.mozilla.javascript.NativeJavaObject.initMembers(NativeJavaObject.java:90)
E/AndroidRuntime( 308): at org.mozilla.javascript.NativeJavaObject.<init>(NativeJavaObject.java:80)
E/AndroidRuntime( 308): at org.mozilla.javascript.NativeJavaObject.<init>(NativeJavaObject.java:70)
E/AndroidRuntime( 308): at org.mozilla.javascript.WrapFactory.wrapAsJavaObject(WrapFactory.java:149)
E/AndroidRuntime( 308): at org.mozilla.javascript.WrapFactory.wrap(WrapFactory.java:105)
E/AndroidRuntime( 308): at org.mozilla.javascript.Context.javaToJS(Context.java:1698)
E/AndroidRuntime( 308): at com.me.android.StartActivity.onCreate(StartActivity.java:34)
E/AndroidRuntime( 308): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime( 308): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
E/AndroidRuntime( 308): ... 11 more
Any insight as to why this is happening would be greatly appreciated.
[EDIT] After some serious googling and head smashing I discovered the ScriptableObject.defineClass
method and tried using that instead, following the examples in the Rhino documentation, however now I get a RuntimeException "ReferenceError: 'DeviceInterface' is not defined." I know this is possible, as Rhino is what the ASE uses for its JavaScript support.
Here is the new code which throws the RuntimeException:
public class StartActivity extends Activity
{
/** Rhino context object */
private Context mCX;
/** Rhino script scope object */
private Scriptable mScope;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create our context and turn off compilation
mCX = Context.enter();
mCX.setOptimizationLevel( -1 );
// Initialize the scope
mScope = mCX.initStandardObjects();
try{
ScriptableObject.defineClass( mScope, DeviceInterface.class );
} catch( Exception e ) {
Log.e("StartActivity", e.toString());
}
// This is the line that throws the exception
mCX.evaluateString(mScope,
"var p = new DeviceInterface();", "",
1, null);
setContentView(R.layout.main);
}
}
And the DeviceInterface class:
public class DeviceInterface extends ScriptableObject
{
static private final long serialVersionUID = 1L;
static public void init ( Scriptable scope )
{
Log.i( "JSInterface", "Init called" );
}
public DeviceInterface()
{
logger( "Created new JSInterface Object" );
}
@Override
public String getClassName()
{
return "DeviceInterface";
}
public void jsFunction_logger( String message )
{
logger( message );
}
private void logger( String message )
{
if( message.contains("[alrt]") )
Log.e( "JSInterface", message );
else if( message.contains("[info]") )
Log.i( "JSInterface", message );
else
Log.d( "JSInterface", message );
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经尝试过你的两个例子:
I have tried both of your examples: