标签:www. btn 推送 future back public color href pac
今天面试没表现好啊,如今来好好研究下这个问题:怎样制作Android无法销毁的Service?(尽管在用户的角度上看。这种开发显得非常无赖,可是非常多场景下,须要这样去设计APP,比如某APP每天在某个固定时间段向用户推送信息,那么手机端这个接收推送服务必须要提前启动。所以做这种事还是非常有必要的)
其实,解决这个还须要一个帮助。运用广播。
在启动Service。调用startService()时。都会调用OnStartCommand(intent。int,int),在当中运行一些方法。来深入了解下OnStartCommand()的四种返回值。
/**
* Constant to return from {@link #onStartCommand}: if this service‘s
* process is killed while it is started (after returning from
* {@link #onStartCommand}), then leave it in the started state but
* don‘t retain this delivered intent. Later the system will try to
* re-create the service. Because it is in the started state, it will
* guarantee to call {@link #onStartCommand} after creating the new
* service instance; if there are not any pending start commands to be
* delivered to the service, it will be called with a null intent
* object, so you must take care to check for this.
*
* <p>This mode makes sense for things that will be explicitly started
* and stopped to run for arbitrary periods of time, such as a service
* performing background music playback.
*/
public static final int START_STICKY = 1;
1.第一种:START_STICKY
public static final int START_STICKY = 1;
假设Service服务被销毁掉,那么保留Service的状态为開始状态,可是并不保留intent对象。
然后系统会创新创建Service。并且之前状态是被保存的開始状态,所以创建Sevice后一定会调用OnStartCommand(intent。int,int),假设在此期间没有其它操作传递到Service,那么intent会为null(由于之前也为保存intent对象,所以会为空)。
/**
* Constant to return from {@link #onStartCommand}: if this service‘s
* process is killed while it is started (after returning from
* {@link #onStartCommand}), and there are no new start intents to
* deliver to it, then take the service out of the started state and
* don‘t recreate until a future explicit call to
* {@link Context#startService Context.startService(Intent)}. The
* service will not receive a {@link #onStartCommand(Intent, int, int)}
* call with a null Intent because it will not be re-started if there
* are no pending Intents to deliver.
*
* <p>This mode makes sense for things that want to do some work as a
* result of being started, but can be stopped when under memory pressure
* and will explicit start themselves again later to do more work. An
* example of such a service would be one that polls for data from
* a server: it could schedule an alarm to poll every N minutes by having
* the alarm start its service. When its {@link #onStartCommand} is
* called from the alarm, it schedules a new alarm for N minutes later,
* and spawns a thread to do its networking. If its process is killed
* while doing that check, the service will not be restarted until the
* alarm goes off.
*/
public static final int START_NOT_STICKY = 2;
另外一种:START_NOT_STICKY
public static final int START_NOT_STICKY = 2;
相当于第一种的对立,“非粘性”。在运行完OnStartCommand后。如服务被异常销毁掉,那么该服务将无法自己主动又一次启动。
/**
* Constant to return from {@link #onStartCommand}: if this service‘s
* process is killed while it is started (after returning from
* {@link #onStartCommand}), then it will be scheduled for a restart
* and the last delivered Intent re-delivered to it again via
* {@link #onStartCommand}. This Intent will remain scheduled for
* redelivery until the service calls {@link #stopSelf(int)} with the
* start ID provided to {@link #onStartCommand}. The
* service will not receive a {@link #onStartCommand(Intent, int, int)}
* call with a null Intent because it will will only be re-started if
* it is not finished processing all Intents sent to it (and any such
* pending events will be delivered at the point of restart).
*/
public static final int START_REDELIVER_INTENT = 3;
第三种:START_REDELIVER_INTENT
public static final int START_REDELIVER_INTENT = 3;
能够从简单的字面上理解。重传intent启动服务,运行完OnStartCommand(intent。int,int)后,假设服务被异常销毁掉。系统会自己主动重新启动服务,并将intent对象传入。
/**
* Constant to return from {@link #onStartCommand}: compatibility
* version of {@link #START_STICKY} that does not guarantee that
* {@link #onStartCommand} will be called again after being killed.
*/
public static final int START_STICKY_COMPATIBILITY = 0;
第四种:START_STICKY_COMPATIBILITY
public static final int START_STICKY_COMPATIBILITY = 0;
从字面上理解是,是第一种的通用类型,只是并不能全然做到能自己主动重新启动服务。
制作一个销毁的Service。或许我们能够不钻牛角尖,做一个能够无限制唤醒的Service,(尽管可被销毁,但服务会再次被创建)
方法一:利用计时,比如60s间隔时间再次启动Service。
例如以下:
MyService:
package com.yyc.servicedemo.services;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service
{
AlarmManager mAlarmManager = null;
PendingIntent mPendingIntent = null;
@Override
public void onCreate() {
//start the service through alarm repeatly
Intent intent = new Intent(getApplicationContext(), MyService.class);
mAlarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
mPendingIntent = PendingIntent.getService(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
long now = System.currentTimeMillis();
mAlarmManager.setInexactRepeating(AlarmManager.RTC, now, 60000, mPendingIntent);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "服务启动", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Toast.makeText(getApplicationContext(),"服务销毁",Toast.LENGTH_SHORT).show();
// /**
// * 另外一种方法
// */
// Intent intent = new Intent();
// intent.setClass(this, MyService.class); // 销毁时又一次启动Service (尽管方法非常流氓)
super.onDestroy();
}
}
MyBroadcastReceiver:
package com.yyc.servicedemo.broadcastReceivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.yyc.servicedemo.services.MyService;
/**
* Created by Administrator on 2016/1/24.
*/
public class MyBroadcastReceiver extends BroadcastReceiver{
private final String TAG=MyBroadcastReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()))
{
Intent startServiceIntent = new Intent(context, MyService.class);
startServiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(startServiceIntent);
}
}
}
另外一种方法:销毁时立马再次创建:
在MySerice内这么写(相比第一种更灵活):
@Override
public void onDestroy() {
Toast.makeText(getApplicationContext(),"服务销毁",Toast.LENGTH_SHORT).show();
/**
* 另外一种方法
*/
Intent intent = new Intent();
intent.setClass(this, MyService.class); // 销毁时又一次启动Service (尽管方法非常流氓)
super.onDestroy();
}
第三种:相似另外一种,我们能够先看张图片:
我们能够注意到微博的方式。最好还是做个假设,微博的服务相互监听。微博的服务仅仅要当中一个服务被销毁。另外的服务就立马创建它,这种“互助”式监听,在一定程度上能够避免APP服务的异常销毁,造成服务无法重新启动,引起APP的异常。
以上这些方面当然还无法去做到真正意义上的无法销毁的服务。假设手机重新启动,全部服务都被销毁了,服务又将怎样自启动呢?那么继续往底层深入的探讨这个问题,个人从网上收集了部分资料。“守护进程”深入到C底层的写法了
举报
这个...
它们能够在无形...
? ?Service与Activity的差别在于...
0条评论