当我将应用更新到新版本时,与之前的应用版本一起安装的服务仍在运行。当我第二次更新应用程序时,更新的服务正在正常运行。
但是,在第一次更新后,每当我关闭应用程序或重新启动手机时,都会运行先前版本的服务。
如何在应用更新后立即强制新服务运行。
这是我的代码
的AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.djuro.updateservicewithappupdate">
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:process=":myService" />
<receiver android:name=".PackageReplacedReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" android:path="com.djuro.updateservicewithappupdate"/>
</intent-filter>
</receiver>
</application>
</manifest>
App.java
public class App extends Application {
private static final String TAG = App.class.getName();
private static App mInstance;
private Messenger myServiceMessenger;
private boolean isBound;
private Messenger replyMessenger = new Messenger(new IncomingHandler());
@Override
public void onCreate() {
super.onCreate();
if (mInstance == null) {
mInstance = this;
startMyService();
}
isBound = false;
// start the chore service (if it is not running) and bind to it
}
public void startMyService() {
startService(new Intent(mInstance, MyService.class));
doBindService();
}
public void stopMyService() {
doUnBindService(true);
stopService(new Intent(mInstance, MyService.class));
}
public static App getInstance() {
return mInstance;
}
public static Context getContext() {
return mInstance.getApplicationContext();
}
public static Messenger getChoreMessenger() {return mInstance.myServiceMessenger;}
@Override
public void onTerminate() {
doUnBindService(false);
super.onTerminate();
}
private void doBindService() {
if (!isBound) {
Log.d(TAG, "Binding ChoreService.");
bindService(new Intent(this, MyService.class), myServiceConnection, Context.BIND_AUTO_CREATE);
isBound = true;
}
}
private void doUnBindService(boolean restartService) {
if (isBound) {
Log.d(TAG, "Unbinding ChoreService.");
if (myServiceMessenger != null) {
try {
Message msg = Message.obtain(null, MyService.UNREGISTER_CLIENT);
msg.replyTo = replyMessenger;
replyMessenger.send(msg);
}
catch (RemoteException e) {
// There is nothing special we need to do if the service has crashed.
}
}
if (restartService) {
try {
Message msg = Message.obtain(null, MyService.STOP_SERVICE_ON_UNBIND);
msg.replyTo = replyMessenger;
replyMessenger.send(msg);
}
catch (RemoteException e) {
// There is nothing special we need to do if the service has crashed.
}
}
unbindService(myServiceConnection);
isBound = false;
} else if (restartService) {
stopService(new Intent(mInstance, MyService.class));
}
}
private ServiceConnection myServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
myServiceMessenger = new Messenger(service);
Log.d(TAG, "connected to service");
try {
Message msg = Message.obtain(null, MyService.REGISTER_CLIENT);
msg.replyTo = replyMessenger;
myServiceMessenger.send(msg);
}
catch (RemoteException e) {
// In this case the service has crashed before we could even do anything with it
}
}
public void onServiceDisconnected(ComponentName className) {
myServiceMessenger = null;
Log.d(TAG, "disconnected from ChoreService");
}
};
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
}
}
}
MyService.java
public class MyService extends Service {
private static final String TAG = MyService.class.getName();
public static final int UNREGISTER_CLIENT = 1;
public static final int REGISTER_CLIENT = 2;
public static final int STOP_SERVICE_ON_UNBIND = 3;
final Messenger messenger = new Messenger(new IncomingHandler());
private String appVersion;
private boolean stopOnUnbind;
private int boundCount = 0;
// called when the intent starts the Service
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
Log.d(TAG, "onStartCommand()");
getVersion();
return START_STICKY;
}
// called once at creation (before onStartCommand)
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
// used to bind intent to service
@Nullable
@Override
public IBinder onBind(Intent intent) {
//doStopForeground();
boundCount ++;
Log.d(TAG, "bound count: " + boundCount);
return messenger.getBinder();
}
@Override
public boolean onUnbind(Intent intent) {
boundCount --;
Log.d(TAG, "bound count: " + boundCount);
boolean result = super.onUnbind(intent);
if (stopOnUnbind) {
Log.d(TAG, "stopSelf()");
stopSelf();
}
return result;
}
// called when the service is destroyed
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy()");
super.onDestroy();
}
public void getVersion() {
try {
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
appVersion = pInfo.versionName;
Log.d(TAG, "appVersion: " + appVersion);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "IncomingHandler handling message. msg.what= " + msg.what);
switch (msg.what) {
case STOP_SERVICE_ON_UNBIND:
stopOnUnbind = true;
break;
default:
super.handleMessage(msg);
break;
}
}
}
}
PackageReplacedReceiver.java
public class PackageReplacedReceiver extends BroadcastReceiver {
private static final String TAG = PackageReplacedReceiver.class.getName();
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "package updated");
App.getInstance().stopMyService();
}
}
答案 0 :(得分:0)
在意图文件管理器中使用android.intent.action.MY_PACKAGE_REPLACED操作,并从广播接收器停止服务。
<receiver android:name=".PackageReplacedReceiver" android:enabled="@bool/is_at_least_api_12" > <intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>