2

Okay, so... have arrived at whits end.

Attempting to learn to utilize the native development kit... starting off with Hello World when the very string "Hello World" is returned from a C source.

To begin: Here's the "main activity".

package com.example.hellojni;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView=(TextView) findViewById(R.id.text1);

        textView.setText(sayHelloWorld());
    }


    private native String sayHelloWorld();

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    static {
        System.loadLibrary("HelloJni");
    }

}

For completeness sake, here's the XML defining the display. I'll bet dollars to doughnuts that this is not where the problem is, but I'd be academically negligent if I didn't mention it.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />

</RelativeLayout>

Following that, we of course need the header file which was generated by javah.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_hellojni_MainActivity */

#ifndef _Included_com_example_hellojni_MainActivity
#define _Included_com_example_hellojni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_hellojni_MainActivity_MODE_PRIVATE
#define com_example_hellojni_MainActivity_MODE_PRIVATE 0L
#undef com_example_hellojni_MainActivity_MODE_WORLD_READABLE
#define com_example_hellojni_MainActivity_MODE_WORLD_READABLE 1L
#undef com_example_hellojni_MainActivity_MODE_WORLD_WRITEABLE
#define com_example_hellojni_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_hellojni_MainActivity_MODE_APPEND
#define com_example_hellojni_MainActivity_MODE_APPEND 32768L
#undef com_example_hellojni_MainActivity_MODE_MULTI_PROCESS
#define com_example_hellojni_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_example_hellojni_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_hellojni_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_hellojni_MainActivity_BIND_AUTO_CREATE
#define com_example_hellojni_MainActivity_BIND_AUTO_CREATE 1L
#undef com_example_hellojni_MainActivity_BIND_DEBUG_UNBIND
#define com_example_hellojni_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_hellojni_MainActivity_BIND_NOT_FOREGROUND
#define com_example_hellojni_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_hellojni_MainActivity_BIND_ABOVE_CLIENT
#define com_example_hellojni_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_hellojni_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_hellojni_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_hellojni_MainActivity_BIND_WAIVE_PRIORITY
#define com_example_hellojni_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_hellojni_MainActivity_BIND_IMPORTANT
#define com_example_hellojni_MainActivity_BIND_IMPORTANT 64L
#undef com_example_hellojni_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_hellojni_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_hellojni_MainActivity_CONTEXT_INCLUDE_CODE
#define com_example_hellojni_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_hellojni_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_example_hellojni_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_hellojni_MainActivity_CONTEXT_RESTRICTED
#define com_example_hellojni_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_example_hellojni_MainActivity_RESULT_CANCELED
#define com_example_hellojni_MainActivity_RESULT_CANCELED 0L
#undef com_example_hellojni_MainActivity_RESULT_OK
#define com_example_hellojni_MainActivity_RESULT_OK -1L
#undef com_example_hellojni_MainActivity_RESULT_FIRST_USER
#define com_example_hellojni_MainActivity_RESULT_FIRST_USER 1L
#undef com_example_hellojni_MainActivity_DEFAULT_KEYS_DISABLE
#define com_example_hellojni_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_hellojni_MainActivity_DEFAULT_KEYS_DIALER
#define com_example_hellojni_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_hellojni_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_hellojni_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_hellojni_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_hellojni_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_hellojni_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_hellojni_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
 * Class:     com_example_hellojni_MainActivity
 * Method:    sayHelloWorld
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_hellojni_MainActivity_sayHelloWorld (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

The next natural thing to look at would be the C source....

#include "com_example_hellojni_MainActivity.h"

jstring Java_com_example_HelloWorldActivity_sayHelloWorld(JNIEnv* pEnv, jobject thiz) {

    return (pEnv->NewStringUTF("Hello World from C!"));

    //return (*pEnv)->NewStringUTF(env,"Hello World from C!");
}

The commented version, I can't remember where I got that from... likely was transcribed as out of a book. In any case, it didn't even compile. The version I used makes much more sense to me. Maybe this is the problem.

Following along, here's android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := HelloJni
LOCAL_SRC_FILES := HelloJni.cpp

include $(BUILD_SHARED_LIBRARY)

And of course... when I put all this together, I get an apk that compiles and attempts to run. The punchline to the joke that I've been pulling my hair out for several days now is below:

03-22 21:34:38.218: I/ActivityManager(322): Start proc com.example.hellojni for activity com.example.hellojni/.MainActivity: pid=20945 uid=10175 gids={}
03-22 21:34:38.278: D/dalvikvm(20945): Trying to load lib /data/data/com.example.hellojni/lib/libHelloJni.so 0x417260f0
03-22 21:34:38.278: D/dalvikvm(20945): Added shared lib /data/data/com.example.hellojni/lib/libHelloJni.so 0x417260f0
03-22 21:34:38.278: D/dalvikvm(20945): No JNI_OnLoad found in /data/data/com.example.hellojni/lib/libHelloJni.so 0x417260f0, skipping init
03-22 21:34:38.318: W/dalvikvm(20945): No implementation found for native Lcom/example/hellojni/MainActivity;.sayHelloWorld ()Ljava/lang/String;
03-22 21:34:38.328: E/AndroidRuntime(20945):    at com.example.hellojni.MainActivity.sayHelloWorld(Native Method)
03-22 21:34:38.328: E/AndroidRuntime(20945):    at com.example.hellojni.MainActivity.onCreate(MainActivity.java:17)
03-22 21:34:38.328: W/ActivityManager(322):   Force finishing activity com.example.hellojni/.MainActivity
03-22 21:34:38.868: W/ActivityManager(322): Activity pause timeout for ActivityRecord{4235a518 com.example.hellojni/.MainActivity}
03-22 21:34:49.008: W/ActivityManager(322): Activity destroy timeout for ActivityRecord{4235a518 com.example.hellojni/.MainActivity}
03-22 21:34:56.208: I/ActivityManager(322): Process com.example.hellojni (pid 20945) has died.

Please help. Frustration is immense, sanity is fading.

Mr Nibbles
  • 131
  • 2
  • 9

1 Answers1

3

Praful Bhatnagar's comment was spot on. I fixed the error that was staring me in the face and everything else fell in to plaece. Thanks!

(not sure if there's something I'm supposed to do to correctly attribute the answer to the person who said it)

Mr Nibbles
  • 131
  • 2
  • 9