目录
5-1.stopService()方法与stopSelf()方法的区别
12.Service应用(二)
3.Bound Service
当应用程序组件通过调用bindService()方法绑定到Service时,Service 处于绑定状态。多个组件可以同时绑定到一个Service上,当它们都解绑定时,Service被销毁。
如果Service仅用于本地应用程序并且不必跨进程工作,则开发人员可以编写自己的Binder 类来为客户端提供访问Service公共方法的方式。
注:这仅当客户端与Service位于同一个应用程序和进程时才有效,这也是最常见的情况。例如,音乐播放器需要将Activity 绑定到自己的Service来在后台播放音乐。
应用程序组件(客户端)能调用bindService()方法绑定到Service,该方法的语法格式如下:
bindService(Intent service, ServiceConnection conn, int flags)
参数说明:
◆service:通过Intent指定要启动的Service。
◆conn:一个 ServiceConnection 对象,该对象用于监听访问者与Service之间的连接情况。
◆flags:指定绑定时是否自动创建Service。该值设置为0时表示不自动创建,设置为BIND_AUTO_ CREATE时表示自动创建。
接下来Android系统调用Service 的onBind()方法,返回 IBinder 对象来与Service通信。
注:只有Activity、Service 和Content Provider能绑定到Service,BroadcastReceiver不能绑定到Service。
例:

BinderService.java
package com.example.randonselectionnumber;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BinderService extends Service {
public BinderService() {
}
//创建MyBinder内部类
public class MyBinder extends Binder{
public BinderService getService(){//创建获取Service的方法
return BinderService.this;//返回当前的Service类
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return new MyBinder();//返回MyBinder Service对象
}
//自定义方法,用于生成随机数
public List getRandomNumber(){
List resArr = new ArrayList();
String strNumber="";//用于保存生成的随机数
for(int i=0;i<7;i++){
//生成指定范围的随机整数
int number=new Random().nextInt(33)+1;
if(number<10){
strNumber="0"+String.valueOf(number);
}else {
strNumber=String.valueOf(number);
}
resArr.add(strNumber);//把转换后的字符串添加到List集合中
}
return resArr;
}
@Override
public void onDestroy() {//销毁Service
super.onDestroy();
}
}
MainActivity.java
package com.example.randonselectionnumber;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
BinderService binderService;//声明Service类的对象
//文本框组件ID
int[] tvid={R.id.mian_tv1,R.id.mian_tv2,R.id.mian_tv3,R.id.mian_tv4,
R.id.mian_tv5,R.id.mian_tv6,R.id.mian_tv7};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar=getSupportActionBar();
actionBar.hide();
Button button=findViewById(R.id.main_btn1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
List number=binderService.getRandomNumber();
for (int i=0;i<number.size();i++){
//获取文本框组件
TextView textView=findViewById(tvid[i]);
//显示生成的随即号码
textView.setText(number.get(i).toString());
}
}
});
}
//创建ServiceConnection对象
private ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//获取后台Service
binderService=((BinderService.MyBinder)iBinder).getService();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onStart() {
super.onStart();
Intent intent=new Intent(MainActivity.this,BinderService.class);
bindService(intent,conn,BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
unbindService(conn);
}
}
4.使用IntentService
IntentService是Service 的子类。
在介绍IntentService之前,先来了解使用Service 时需要注意的两个问题:
◆Service 不会专门启动一个线程来执行耗时操作,所有的操作都是在主线程中进行的,以至于容易出现ANR (Application Not Responding)的情况。所以需要手动开启一个子线程。
◆Service 不会自动停止,需要调用stopSelf()方法或者是stopService()方法来停止。
而使用IntentService,则不会出现这两个问题。因为IntentService在开启Service时,会自动开启一个新的线程来执行它。另外,当Service 运行结束后会自动停止。
例如,如果把在 2-1 小节中创建的MyService修改为继承IntentService,则可以使用下面的代码来模拟执行一段耗时任务,并测试其开启和停止。
package com.example.demo;
import android.app.IntentService;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class MyService extends IntentService {
public MyService() {
super("MyService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.i("IntentService","Service已启动");
//模拟一段耗时任务
long endTime=System.currentTimeMillis()+5*1000;
while (System.currentTimeMillis()<endTime){
synchronized (this){
try {
wait(endTime-System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onDestroy() {
Log.i("IntentService","Service已停止");
}
}
Logcat面板将输出:

从上面的代码中,可以看出使用IntentService执行耗时操作时不需要手动开启线程和停止Service。
5.难点解答
5-1.stopService()方法与stopSelf()方法的区别
stopService()方法执行后将直接执行onDestroy()方法进行Service的销毁;而stopSelf()方法执行后并不会立刻执行onDestroy()方法,而是等待onStartCommand()方法执行完才执行onDestroy()方法,进行Service的销毁。
5-2.不同类型Service之间的区别
普通Service不会专门启动一个单独的线程,所以不是在新创建的Worker线程中,就不应该在Service中直接处理耗时任务。Service 启动后在没有执行stopService()方法时,即使关闭当前应用后Service也将继续执行。销毁该应用资源后,Service 将自动停止。
Bound Service是当应用程序组件通过调用bindService()方法绑定到Service时,即可实现应用程序组件与Service之间的信息传递。解除绑定后将无法进行与Service的通讯。
IntentService是Service的子类,而IntentService将会使用列队来管理请求Intent,并开启一条新的Worker线程来处理该Intent。因此,IntentService 不会阻塞主线程,它可以自己处理耗时任务。
本文深入探讨Android中的Service,讲解了Bound Service的绑定过程与使用,以及IntentService如何解决耗时操作的问题。同时,文章还分析了stopService()与stopSelf()的区别以及不同类型Service的特性。
&spm=1001.2101.3001.5002&articleId=125858613&d=1&t=3&u=29753993f087429699e03310fd181146)
1703

被折叠的 条评论
为什么被折叠?



