服务部依赖于任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用程序。服务仍然能够保持运行。
当某个应用程序进程被杀死后,所依赖与该进程的服务也会停止运行。
服务并不会自动开启线程,所有的代码都是默认运行在主线程当中,也就是说我们需要在服务内部手动创建子线程,并在这里执行具体任务。
Android的ui是线程不安全的。也就是说,如果想要更新应用程序里的ui元素,必须在主线程中进行,否则会出现异常。
这是一个基本的服务。BInder对象是服务和活动通讯的桥梁。
一旦调用了startService方法,相应的服务就会起来,并回调onStartCommond()方法。如果这个服务之前还没有被创建过,oncreate方法会先于onStartCommand()方法执行,服务启动之后一直处与运行的状态,直到调用一次stopService或者stopself方法。每个服务都只存在一个实例,不管你调用多少次startService,只需调用一次stopService方法或者stopSelf方法。服务就会停止。
另外,如果调用bindService方法来获取一个服务的持久连接,这时就会回调onBInd方法。如果这个服务还没有被创建过,onCreate方法会吸纳与onBInd方法执行。调用方法后可返回实例。
调用了bindService方法后用调用startService方法,那么要同时调用stopService方法和unbindService方法。onDestroy方法才能执行。
package com.example.servicetest;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private DownloadBinder mBinder = new DownloadBinder();
class DownloadBinder extends Binder {
public void startDownload() {
new Thread(new Runnable() {
@Override
public void run() {
// start downloading
}
}).start();
Log.d("MyService", "startDownload executed");
}
public int getProgress() {
Log.d("MyService", "getProgress executed");
return 0;
}
}
@Override
public IBinder onBind(Intent intent) {
Log.d("MyService", "onBind executed");
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
Notification notification = new Notification(R.drawable.ic_launcher,
"Notification comes", System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(this, "This is title", "This is content",
pendingIntent);
startForeground(1, notification);
Log.d("MyService", "onCreate executed");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "onStartCommand executed");
new Thread(new Runnable() {
@Override
public void run() {
// do something here
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "onDestroy executed");
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_service:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent);
break;
case R.id.stop_service:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent);
break;
case R.id.bind_service:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
break;
case R.id.unbind_service:
unbindService(connection);
break;
case R.id.start_intent_service:
Log.d("MainActivity", "Thread id is " + Thread.currentThread().getId());
Intent intentService = new Intent(this, MyIntentService.class);
startService(intentService);
break;
default:
break;
}
}
后台执行的定时任务,这里执行一个打印时间的例子。
MainActivity.java 在这里启动服务
package com.example.servicebestpractice;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
View view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, LongRunningService.class);
startService(intent);
}
}
package com.example.servicebestpractice;
import java.util.Date;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
public class LongRunningService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
Log.d("LongRunningService", "executed at " + new Date().toString());
}
}).start();
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
int anHour = 60 * 1000;
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent i = new Intent(this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
Log.d("LongRunningService", "2");
return super.onStartCommand(intent, flags, startId);
}
}
package com.example.servicebestpractice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("LongRunningService", "1");
Intent i = new Intent(context, LongRunningService.class);
context.startService(i);
}
}