Calling a multiple parameters Java method with JNI (Loading ETC1 for Android)

Calling a Java method from C++ with JNI is kind of difficult since you don’t have static type compilation errors.

I was calling a Java method from my Android OpenGL graphics module in order to load an ETC1 texture with this command:

jmethodID mid = env->GetMethodID(cls, "LoadETC1", "(Ljava/lang/String; [I [I)I");

The Java method I was trying to call was the following:

		public int LoadETC1(String s, int[] w1, int[] h1)
		{
			if (!ETC1Util.isETC1Supported())
				return 0;
			try {
				InputStream s2 = assetManager.open(s);
				ETC1Util.ETC1Texture t = ETC1Util.createTexture(s2);
				int textureName = -1;
				int[] texture = new int[1];
				GLES20.glGenTextures(1, texture, 0);
				textureName = texture[0];

		        GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureName );

//				GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

		        int w = t.getWidth();
		        int h = t.getHeight();
		        int l = t.getData().capacity();
		        GLES20.glCompressedTexImage2D(GLES20.GL_TEXTURE_2D, 0, ETC1.ETC1_RGB8_OES, t.getWidth(), t.getHeight(), 0, t.getData().capacity(), t.getData());
//		        GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, w, h, 0,
//		                              GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib );

		        GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
		        GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
		        GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT );
		        GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT );
		        TextureNode n = new TextureNode();
		        w1[0] = t.getWidth();
		        h1[0] = t.getHeight();
		        return texture[0];
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return 0;
		}

The issue was that  GetMethodID was returning 0. In LogCat it mentioned that my method signature is bogus “(Ljava/lang/String; [I [I)I“.

The issue actually was that I had spaces between the 3 parameters of the method. There should be no spaces and there should be ‘;’ only after a non primitive Java class like “Ljava/lang/String;”.

The following method gave a valid jmethodID:

jmethodID mid = env->GetMethodID(cls, "LoadETC1", "(Ljava/lang/String;[I[I)I");

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s