Reputation: 365
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
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