可以长时间运行在后台的不可见的没有界面的组件
运行在主线程中
可以跨进程调用
因为service是Android中实现程序后台运行的解决方案,非常适合那些不需要与用户进行交互且需要长期运行的任务。
startService和bindService两种
public class MyService extends Service {
public void onCreate() {
super.onCreate();
Log.e(TAG+Thread.currentThread().toString(), "onCreate: " );
}
当重复调用Service时,会重复执行
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
Log.e(TAG, "onBind: " );
throw new UnsupportedOperationException("Not yet implemented");
//return mBinder;
}
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy: " );
}
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">service>
startIntent = new Intent(MainActivity.this,MyService.class);
this.startService(startIntent);
this.stopService(startIntent);
"http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.servicetest.MainActivity">
id="@+id/main_et"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
text=""
android:gravity="center"
android:textSize="30sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/main_tv"/>
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
//重写onCreate(),打印
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG+Thread.currentThread().toString(), "onCreate: " );
}
//重写onStartCommand,打印,在里面写一个子线程,实现倒计时功能
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand: " );
new Thread(new Runnable() {
@Override
public void run() {
for(int i=10;i>=0;i--){
Log.e(TAG+Thread.currentThread().toString(), "run: "+"----"+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
//重写onBind()方法
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
Log.e(TAG, "onBind: " );
throw new UnsupportedOperationException("Not yet implemented");
// return mBinder;
}
// private DownloadBinder mBinder = new DownloadBinder();
// class DownloadBinder extends Binder{
//
// public void startDownload (){
// Log.e(TAG, "startDownload: " );
//
// }
// public int getProgress(){
// Log.e(TAG, "getProgress: " );
// return 0;
// }
//
// }
//重写onDestroy()
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy: " );
}
}
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button startBtn;
private Button stopBtn;
private Button bindBtn;
private Button unBindBtn;
private EditText editText;
private TextView textView;
private Intent startIntent;
// private MyService.DownloadBinder downloadBinder ;
// private ServiceConnection connection = new ServiceConnection() {
// @Override
// public void onServiceConnected(ComponentName name, IBinder service) {
// downloadBinder = (MyService.DownloadBinder) service;
// downloadBinder.startDownload();
// downloadBinder.getProgress();
//
// }
//
// @Override
// public void onServiceDisconnected(ComponentName name) {
//
// }
// };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bangID();
}
private void bangID() {
startBtn = findViewById(R.id.main_start_btn);
stopBtn = findViewById(R.id.main_stop_btn);
bindBtn = findViewById(R.id.main_bind_btn);
unBindBtn = findViewById(R.id.main_unbind_btn);
editText = findViewById(R.id.main_et);
textView = findViewById(R.id.main_tv);
startBtn.setOnClickListener(this);
stopBtn.setOnClickListener(this);
bindBtn.setOnClickListener(this);
unBindBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_start_btn:
//启动服务
startIntent = new Intent(MainActivity.this,MyService.class);
this.startService(startIntent);
break;
case R.id.main_stop_btn:
//关闭服务
this.stopService(startIntent);
break;
// case R.id.main_bind_btn:
// Intent bindIntent = new Intent(MainActivity.this,MyService.class);
// this.bindService(bindIntent,connection,BIND_AUTO_CREATE);
// break;
// case R.id.main_unbind_btn:
// unbindService(connection);
// break;
default:
}
}
}
startservce使用特点:onCreate只会在创建service时执行一次,只要调用startService,onStartCommand一定会执行
startservice启动服务的优点:代码较为简洁,而缺点是,无法很好的控制服务,不能直接调用service中的方法,传值只能通过intent来传递。
//重写onBind()方法,返回管家对象
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind: ");
//throw new UnsupportedOperationException("Not yet implemented");
return guanjia;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
//创建管家对象
private Guanjia guanjia = new Guanjia();
//使用bindservice启动service,需要在MyService中添加自定义类,继承Binder类,返回MyService.this
//这里相当于创建了一个管家,获得了service的信任,以后就可以在context环境中通过管家获得service对象
class Guanjia extends Binder {
public MyService getServiceObject() {
return MyService.this;
}
}
public void printDemo() {
Log.e(TAG, "printDemo: " + "我挥舞着键盘,发誓要将这个世界写的明明白白");
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e(TAG, "onServiceConnected: " );
MyService myService = ((MyService.Guanjia) service).getServiceObject();
myService.printDemo();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "onServiceDisconnected: " );
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, "onCreate: "+"++" );
bangID();
}
private void bangID() {
startBtn = findViewById(R.id.main_start_btn);
stopBtn = findViewById(R.id.main_stop_btn);
bindBtn = findViewById(R.id.main_bind_btn);
unBindBtn = findViewById(R.id.main_unbind_btn);
toBBtn = findViewById(R.id.main_to_b_btn);
startBtn.setOnClickListener(this);
stopBtn.setOnClickListener(this);
bindBtn.setOnClickListener(this);
unBindBtn.setOnClickListener(this);
toBBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_start_btn:
//启动服务
startIntent = new Intent(MainActivity.this,MyIntentService.class);
this.startService(startIntent);
break;
case R.id.main_stop_btn:
//关闭服务
this.stopService(startIntent);
break;
case R.id.main_bind_btn:
Log.e(TAG, "bindService: " );
//启动绑定服务
bindIntent = new Intent(MainActivity.this,MyService.class);
/**
* param:1:intent对对象
* param2:serviceconnection实例
* param3:标志位,这里意思是自动完成绑定后自动创建服务
*/
this.bindService(bindIntent,connection,BIND_AUTO_CREATE);
break;
case R.id.main_unbind_btn:
Log.e(TAG, "unbindService: " );
//停止绑定
unbindService(connection);
break;
case R.id.main_to_b_btn:
Intent intent = new Intent(this,BActivity.class);
startActivity(intent);
break;
default:
}
}
}
bindservice的特点:onCreate,onBind只会执行一次
使用优点:可以直接操作Service中的属性和方法。
缺点:创建service对象较为复杂
IntentService 是继承于 Service 并处理异步请求的一个类
在 IntentService 内有一个工作线程来处理耗时操作,启动 IntentService 的方式和启动传统 Service 一样,同时,当任务执行完后,IntentService 会自动停止,而不需要我们去手动控制。另外,可以启动 IntentService 多次,而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推
首先,我们省去了在 Service 中手动开线程的麻烦,第二,当操作完成时,我们不用手动停止 Service
public class MyIntentService extends IntentService{
private String TAG = "MyIntentService";
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
//重新建一个默认的构造方法,要没有参数
public MyIntentService(){
super("");
}
//重写onHandleIntent方法,可以看到我们可以直接进行耗时操作,那是因为服务自带子线程
@Override
protected void onHandleIntent(@Nullable Intent intent) {
for(int i = 10;i>=0;i--){
Log.e(TAG, "onHandleIntent: " +i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_start_btn:
//启动服务
startIntent = new Intent(MainActivity.this,MyIntentService.class);
this.startService(startIntent);
break;
case R.id.main_stop_btn:
//关闭服务
this.stopService(startIntent);
break;
service:Service 不是一个单独的进程,它和应用程序在同一个进程中,Service 也不是一个线程,它和线程没有任何关系,所以它不能直接处理耗时操作。如果有耗时操作就必须开启一个单独的线程来处理
IntentService: 是继承于 Service 并处理异步请求的一个类,在 IntentService 内有一个工作线程来处理耗时操作,启动 IntentService 的方式和启动传统 Service 一样,同时,当任务执行完后,IntentService 会自动停止,而不需要我们去手动控制。另外,可以启动 IntentService 多次,而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推