dnl
dnl

Reputation: 365

JNI Error using CordovaWebView in Android App

My Android app uses Cordova/PhoneGap to implement the business logic on the JavaScript side. So there is a single activity that loads a CordovaWebView and afterwards some fragments to provide native UI elements.

Here is the Activity's onCreate method and its startFragment method to instantiate a new fragment

public class MyPhoneGapActivity extends
    SherlockFragmentActivity implements CordovaInterface {

    private static CordovaWebView sGlobalCordovaWebView;
    private final ExecutorService mThreadPool = Executors.newCachedThreadPool();
    private SherlockFragment mLatestFragment;
    private Bundle mSavedInstanceState;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.mSavedInstanceState = savedInstanceState;

        setIntegerProperty("loadUrlTimeoutValue", 60000);
        setContentView(R.layout.phonegap_activity);

        sGlobalCordovaWebView = (CordovaWebView) findViewById(R.id.phonegap_activity_cordovawebview);
        sGlobalCordovaWebView.loadUrl("file:///android_asset/www/index.html");

        startFragment("com.acme.view.ExampleScreenView");
    }

    public SherlockFragment startFragment(String name) throws RuntimeException {
        try {

            mLatestFragment = (SherlockFragment) SherlockFragment.instantiate(getActivity(),
                Class.forName(name).getName());

            getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.phonegap_activity_fragment,
                        mLatestFragment, "activityFragment").commit();
            getSupportFragmentManager().executePendingTransactions();

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(
                "startFragment: The class for the desired fragment could not be found.");
        }
        return mLatestFragment;
    }
}

But it leads to a JNI Error when running the app on my HTC EVO device:

01-04 17:58:11.537: E/dalvikvm(5451): JNI ERROR (app bug): attempt to use stale local     reference 0x1
01-04 17:58:11.537: E/dalvikvm(5451): VM aborting
01-04 17:58:11.537: A/libc(5451): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1)
01-04 17:58:11.967: I/DEBUG(5047): debuggerd: 2013-01-04 17:58:11
01-04 17:58:11.967: I/DEBUG(5047): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-04 17:58:11.967: I/DEBUG(5047): Build fingerprint: 'htc_europe/htc_shooteru/shooteru:4.0.3/IML74K/385730.1:user/release-keys'
01-04 17:58:11.967: I/DEBUG(5047): pid: 5451, tid: 5531  >>> eu.mobilion.wasserfinder <<<
01-04 17:58:11.967: I/DEBUG(5047): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
01-04 17:58:11.967: I/DEBUG(5047):  r0 00000000  r1 00c34d48  r2 00000000  r3 00000000
01-04 17:58:11.967: I/DEBUG(5047):  r4 deadd00d  r5 40950ce8  r6 0000020c  r7 52131900
01-04 17:58:11.967: I/DEBUG(5047):  r8 01320c50  r9 27600005  10 0000000c  fp 0127c3d0
01-04 17:58:11.967: I/DEBUG(5047):  ip 00000000  sp 52131650  lr 408e82db  pc 408e82da  cpsr 60000030
01-04 17:58:11.967: I/DEBUG(5047):  d0  0000000000000000  d1  0000000000000000
...
01-04 17:58:11.977: I/DEBUG(5047):  d30 0000000000000000  d31 3ff0000000000000
01-04 17:58:11.977: I/DEBUG(5047):  scr 60000013
01-04 17:58:12.247: I/DEBUG(5047):          #00  pc 000512da  /system/lib/libdvm.so (dvmAbort)
01-04 17:58:12.247: I/DEBUG(5047):          #01  pc 000326b8  /system/lib/libdvm.so (_ZNK16IndirectRefTable3getEPv)
01-04 17:58:12.247: I/DEBUG(5047):          #02  pc 00055ea4  /system/lib/libdvm.so (_Z20dvmDecodeIndirectRefP6ThreadP8_jobject)
01-04 17:58:12.247: I/DEBUG(5047):          #03  pc 0005724c  /system/lib/libdvm.so
01-04 17:58:12.247: I/DEBUG(5047):          #04  pc 0022707e  /system/lib/libwebcore.so
01-04 17:58:12.247: I/DEBUG(5047):          #05  pc 003ee990  /system/lib/libwebcore.so
01-04 17:58:12.247: I/DEBUG(5047):          #06  pc 003a2cd2  /system/lib/libwebcore.so
01-04 17:58:12.247: I/DEBUG(5047):          #07  pc 003a30ca  /system/lib/libwebcore.so
...

When commenting the line sGlobalCordovaWebView.loadUrl("file:///android_asset/www/index.html") the app starts and show up the native UI including all fragments, but of course does not have any functionality due to missing JavaScript logic.

I took notice of android JNI ERROR but I did not do the trick for me.


EDIT: phonegap_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <org.apache.cordova.CordovaWebView
        android:id="@+id/phonegap_activity_cordovawebview"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:visibility="invisible" />

    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_below="@+id/phonegap_activity_cordovawebview"
        android:id="@+id/phonegap_activity_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>

</RelativeLayout>

Upvotes: 0

Views: 819

Answers (1)

dnl
dnl

Reputation: 365

Solved this issue. The trick was to use getActivity().runOnUiThread(..) within the cordova plugin and put all UI creation stuff and fragment starts into it. E.g.

 public class MyPlugin extends CordovaPlugin {

     public boolean execute(String action, final JSONArray jA, final CallbackContext cC) {
         if (action.equals("myAction"))
             return doSth(action, jA, cC);
     }

     private boolean doSth(String action, final JSONArray jA, final CallbackContext cC) {
         getActivity().runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 // start fragment with UI stuff ....
             }
         }
         cC.success(); 
         return true;
     }

 }

Upvotes: 2

Related Questions