|
15 | 15 | import android.util.Log; |
16 | 16 | import android.app.Activity; |
17 | 17 | import android.content.Context; |
| 18 | +import android.content.Intent; |
18 | 19 | import android.content.res.AssetManager; |
19 | 20 | import android.content.pm.PackageInfo; |
20 | 21 | import android.content.pm.PackageManager; |
@@ -50,6 +51,7 @@ public class NodeJS extends CordovaPlugin { |
50 | 51 |
|
51 | 52 | private static final String SHARED_PREFS = "NODEJS_MOBILE_PREFS"; |
52 | 53 | private static final String LAST_UPDATED_TIME = "NODEJS_MOBILE_APK_LastUpdateTime"; |
| 54 | + private static final String FORCE_RESET = "NODEJS_MOBILE_RESET"; |
53 | 55 | private long lastUpdateTime = 1; |
54 | 56 | private long previousLastUpdateTime = 0; |
55 | 57 |
|
@@ -107,7 +109,7 @@ public void pluginInitialize() { |
107 | 109 | } |
108 | 110 |
|
109 | 111 | private void asyncInit() { |
110 | | - if (wasAPKUpdated() || isEmptyNodeModules()) { |
| 112 | + if (wasAPKUpdated() || isReset()) { |
111 | 113 | try { |
112 | 114 | initSemaphore.acquire(); |
113 | 115 | new Thread(new Runnable() { |
@@ -151,6 +153,8 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo |
151 | 153 | String scriptBody = data.getString(0); |
152 | 154 | JSONObject startOptions = data.getJSONObject(1); |
153 | 155 | this.startEngineWithScript(scriptBody, startOptions, callbackContext); |
| 156 | + } else if (action.equals("reset")) { |
| 157 | + this.setReset(); |
154 | 158 | } else { |
155 | 159 | Log.e(LOGTAG, "Invalid action: " + action); |
156 | 160 | return false; |
@@ -367,6 +371,28 @@ private boolean isEmptyNodeModules(){ |
367 | 371 | return !nodejsModulesFolder.exists(); |
368 | 372 | } |
369 | 373 |
|
| 374 | + private void setReset() { |
| 375 | + SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE); |
| 376 | + SharedPreferences.Editor editor = prefs.edit(); |
| 377 | + editor.putBoolean(FORCE_RESET, true); |
| 378 | + editor.commit(); |
| 379 | + doColdRestart(); |
| 380 | + } |
| 381 | + |
| 382 | + private void clearReset() { |
| 383 | + SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE); |
| 384 | + SharedPreferences.Editor editor = prefs.edit(); |
| 385 | + editor.remove(FORCE_RESET); |
| 386 | + editor.commit(); |
| 387 | + } |
| 388 | + |
| 389 | + private boolean isReset() { |
| 390 | + SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE); |
| 391 | + boolean result = prefs.getBoolean(FORCE_RESET, false); |
| 392 | + clearReset(); |
| 393 | + return result; |
| 394 | + } |
| 395 | + |
370 | 396 | private boolean wasAPKUpdated() { |
371 | 397 | SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE); |
372 | 398 | this.previousLastUpdateTime = prefs.getLong(LAST_UPDATED_TIME, 0); |
@@ -578,4 +604,54 @@ private static boolean getOptionRedirectOutputToLogcat(final JSONObject startOpt |
578 | 604 | } |
579 | 605 | return result; |
580 | 606 | } |
| 607 | + |
| 608 | + /** |
| 609 | + * Performs a full cold app restart - restarts application |
| 610 | + * https://stackoverflow.com/a/22345538/777265 |
| 611 | + */ |
| 612 | + protected void doColdRestart() { |
| 613 | + String baseError = "Unable to cold restart application: "; |
| 614 | + try { |
| 615 | + Log.d(LOGTAG, "Cold restarting application"); |
| 616 | + Context c = context; |
| 617 | + //check if the context is given |
| 618 | + if (c != null) { |
| 619 | + //fetch the packagemanager so we can get the default launch activity |
| 620 | + // (you can replace this intent with any other activity if you want |
| 621 | + PackageManager pm = c.getPackageManager(); |
| 622 | + //check if we got the PackageManager |
| 623 | + if (pm != null) { |
| 624 | + //create the intent with the default start activity for your application |
| 625 | + Intent mStartActivity = pm.getLaunchIntentForPackage( |
| 626 | + c.getPackageName() |
| 627 | + ); |
| 628 | + if (mStartActivity != null) { |
| 629 | + //mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); |
| 630 | + //create a pending intent so the application is restarted after System.exit(0) was called. |
| 631 | + // We use an AlarmManager to call this intent in 100ms |
| 632 | + // int mPendingIntentId = 223344; |
| 633 | + // PendingIntent mPendingIntent = PendingIntent |
| 634 | + // .getActivity(c, mPendingIntentId, mStartActivity, |
| 635 | + // PendingIntent.FLAG_CANCEL_CURRENT); |
| 636 | + // AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE); |
| 637 | + // mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); |
| 638 | + mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); |
| 639 | + c.getApplicationContext().startActivity(mStartActivity); |
| 640 | + |
| 641 | + Log.i(LOGTAG,"Killing application for cold restart"); |
| 642 | + //kill the application |
| 643 | + System.exit(0); |
| 644 | + } else { |
| 645 | + Log.e(LOGTAG, baseError + "StartActivity is null"); |
| 646 | + } |
| 647 | + } else { |
| 648 | + Log.e(LOGTAG, baseError + "PackageManager is null"); |
| 649 | + } |
| 650 | + } else { |
| 651 | + Log.e(LOGTAG, baseError + "Context is null"); |
| 652 | + } |
| 653 | + } catch (Exception ex) { |
| 654 | + ex.printStackTrace(); |
| 655 | + } |
| 656 | + } |
581 | 657 | } |
0 commit comments