-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Move PhoenixActivity to a separate class * Add support for restarting a Service. * Apply suggestions from code review Co-authored-by: Jake Wharton <[email protected]> * Split Activity and Service methods, keeping the existing methods Activity-only. * Run spotless code formatting --------- Co-authored-by: jobhh <[email protected]> Co-authored-by: Jake Wharton <[email protected]>
- Loading branch information
1 parent
ceaf29c
commit 21907fb
Showing
9 changed files
with
293 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
process-phoenix/src/main/java/com/jakewharton/processphoenix/PhoenixActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.jakewharton.processphoenix; | ||
|
||
import android.app.Activity; | ||
import android.content.Intent; | ||
import android.os.Build; | ||
import android.os.Bundle; | ||
import android.os.Process; | ||
import android.os.StrictMode; | ||
|
||
public final class PhoenixActivity extends Activity { | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
// Kill original main process | ||
Process.killProcess(getIntent().getIntExtra(ProcessPhoenix.KEY_MAIN_PROCESS_PID, -1)); | ||
|
||
Intent[] intents = | ||
getIntent() | ||
.<Intent>getParcelableArrayListExtra(ProcessPhoenix.KEY_RESTART_INTENTS) | ||
.toArray(new Intent[0]); | ||
|
||
if (Build.VERSION.SDK_INT > 31) { | ||
// Disable strict mode complaining about out-of-process intents. Normally you save and restore | ||
// the original policy, but this process will die almost immediately after the offending call. | ||
StrictMode.setVmPolicy( | ||
new StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy()) | ||
.permitUnsafeIntentLaunch() | ||
.build()); | ||
} | ||
|
||
startActivities(intents); | ||
finish(); | ||
Runtime.getRuntime().exit(0); // Kill kill kill! | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
process-phoenix/src/main/java/com/jakewharton/processphoenix/PhoenixService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package com.jakewharton.processphoenix; | ||
|
||
import android.app.IntentService; | ||
import android.content.Intent; | ||
import android.os.Build; | ||
import android.os.Process; | ||
import android.os.StrictMode; | ||
|
||
/** | ||
* Please note that restarting a Service multiple times can result in an increasingly long delay between restart times. | ||
* This is a safety mechanism, since Android registers the restart of this service as a crashed service. | ||
* <p> | ||
* The observed delay periods are: 1s, 4s, 16s, 64s, 256s, 1024s. (on an Android 11 device) | ||
* Which seems to follow this pattern: 4^x, with x being the restart attempt minus 1. | ||
*/ | ||
public final class PhoenixService extends IntentService { | ||
|
||
public PhoenixService() { | ||
super("PhoenixService"); | ||
} | ||
|
||
@Override | ||
protected void onHandleIntent(Intent intent) { | ||
if (intent == null) { | ||
return; | ||
} | ||
|
||
Process.killProcess( | ||
intent.getIntExtra(ProcessPhoenix.KEY_MAIN_PROCESS_PID, -1)); // Kill original main process | ||
|
||
Intent nextIntent; | ||
if (Build.VERSION.SDK_INT >= 33) { | ||
nextIntent = intent.getParcelableExtra(ProcessPhoenix.KEY_RESTART_INTENT, Intent.class); | ||
} else { | ||
nextIntent = intent.getParcelableExtra(ProcessPhoenix.KEY_RESTART_INTENT); | ||
} | ||
|
||
if (Build.VERSION.SDK_INT > 31) { | ||
// Disable strict mode complaining about out-of-process intents. Normally you save and restore | ||
// the original policy, but this process will die almost immediately after the offending call. | ||
StrictMode.setVmPolicy( | ||
new StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy()) | ||
.permitUnsafeIntentLaunch() | ||
.build()); | ||
} | ||
|
||
if (Build.VERSION.SDK_INT >= 26) { | ||
startForegroundService(nextIntent); | ||
} else { | ||
startService(nextIntent); | ||
} | ||
|
||
Runtime.getRuntime().exit(0); // Kill kill kill! | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
sample/src/main/java/com/jakewharton/processphoenix/sample/NotificationBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.jakewharton.processphoenix.sample; | ||
|
||
import android.Manifest; | ||
import android.annotation.TargetApi; | ||
import android.app.Notification; | ||
import android.app.NotificationChannel; | ||
import android.app.NotificationManager; | ||
import android.content.Context; | ||
import android.content.pm.PackageManager; | ||
import android.os.Build; | ||
import android.util.Log; | ||
|
||
public final class NotificationBuilder { | ||
|
||
/** | ||
* Create a Notification, required to support Service restarting on Android 8 and newer | ||
*/ | ||
@TargetApi(26) | ||
public static Notification createNotification(Context context) { | ||
// Android 13 or higher requires a permission to post Notifications | ||
if (Build.VERSION.SDK_INT >= 33) { | ||
if (context.checkCallingOrSelfPermission(Manifest.permission.POST_NOTIFICATIONS) | ||
!= PackageManager.PERMISSION_GRANTED) { | ||
Log.e( | ||
"ProcessPhoenix", | ||
"Required POST_NOTIFICATIONS permission was not granted, cannot restart Service"); | ||
return null; | ||
} | ||
} | ||
|
||
// Android 8 or higher requires a Notification Channel | ||
if (Build.VERSION.SDK_INT >= 26) { | ||
// Creating an existing notification channel with its original values performs no operation, | ||
// so it's safe to call this code multiple times | ||
NotificationChannel channel = | ||
new NotificationChannel( | ||
"ProcessPhoenix", "ProcessPhoenix", NotificationManager.IMPORTANCE_NONE); | ||
|
||
// Create Notification Channel | ||
NotificationManager notificationManager = | ||
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); | ||
notificationManager.createNotificationChannel(channel); | ||
} | ||
|
||
// Create a Notification | ||
return new Notification.Builder(context, "ProcessPhoenix") | ||
.setSmallIcon(android.R.mipmap.sym_def_app_icon) | ||
.setContentTitle("ProcessPhoenix") | ||
.setContentText("PhoenixService") | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.