Android学习笔记之Service

2018-10-19  本文已影响0人  sssssss_

1.Service 是什么?

Service 是 Android 中实现程序后台运行的解决方案,非常适用于去执行那些不需要和用户交互而且还要求长期运行的任务。Service默认运行在UI主线程中,所以不能做耗时操作,只能在Service中创建子线程来完成耗时操作。


补充说明:Service有两种启动方式,startService()bindService(),它们之间的区别是:


2.Service 的生命周期

Service 的生命周期

3.Service的基本用法(startService、bindService和IntentService)

3.1 startService

  • 第一步:新建类并继承Service且必须重写onBind()方法,有选择的重写onCreate()、onStartCommand()及onDestroy()方法。
  • 第二步:在配置文件AndroidManifest.xml中进行注册,否则不能生效。
  • 第三步:在 Activity 中利用 startService(Intent) 可实现 Service 的启动。
  • 第四步:在 Activity 中 stopService(Intent) 停止服务,或者在Service任意位置调用stopSelf();
public class MyService extends Service {

    public MyService() {
    }
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //处理具体的逻辑
                //必须调用stopService或者stopSelf方法才能停止
                stopSelf();
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
//在配置文件AndroidManifest.xml中进行注册
<service
    android:name=".MyService"
    android:enabled="true"
    android:exported="true" />

//启动
Intent intent = new Intent(this, MyService.class);
 startService(intent);
//停止
Intent intent = new Intent(this, MyService.class);
stopService(intent);

3.2 bindService

  • 第一步:创建BindService服务端,继承自Service,并在类中创建一个实例IBinder接口实现对象并提供公共方法给客户端调用。
  • 第二步:从 onBind() 回调方法返回此Binder实例;
  • 第三步:在客户端中,从onServiceConnected()回调方法接收Binder,并使用提供的方法调用绑定服务。
  • 绑定服务提供了客户端和服务端接口,进行数据的交互(发送请求、获取结果、进程间通信)
public class TestService extends Service {
    private Mybinder mBinder = new Mybinder();
    public TestService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    public class Mybinder extends Binder {
        public void showToast() {
            Toast.makeText(getApplicationContext(), "BindService", Toast.LENGTH_SHORT).show();
        }
    }
}

public class MainActivity extends AppCompatActivity {
    private TestService.Mybinder mBinder;
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //成功绑定
            mBinder = (TestService.Mybinder) service;
            mBinder.showToast();
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            //断开连接
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //绑定服务
        Intent bindIntent = new Intent(this, TestService.class);
        bindService(bindIntent, mConnection, BIND_AUTO_CREATE);
        //解绑服务
        unbindService(mConnection);
    }
}

3.3 IntentService

第一步:新建类并继承IntentService,在这里需要提供一个无参的构造函数且必须在其内部调用父类的有参构造函数,然后具体实现在onHandleIntent()方法,这里可以去处理一些耗时操作而不用担心 ANR 的问题,因为这个方法已经是在子线程中运行的了。
第二步:在配置文件中进行注册。
第三步:在活动中利用startService(Intent)实现IntentService的启动,和Service用的方法是完全一样的。

public class MyIntentService extends IntentService {

    public MyIntentService() {
        super("MyIntentService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        //子线程 耗时操作
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}
//调用方法
Intent intentService = new Intent(this, MyIntentService.class);
startService(intentService);

4.Activity如何与Service通信?

在 Activity 中可以通过 startService 和 bindService 方法启动 Service。一般情况下如果想获取 Service 的服务对象那么肯定需要通过bindService()方法,比如音乐播放器,第三方支付等。如果仅仅只是为了开启一个后台任务那么可以使用 startService() 方法。

  1. 首先定义 MyService 来指定具体的操作。
  2. 先在 Activity 里实现一个ServiceConnection类 connection,重写 onServiceConnected 和 onServiceDisconnected 方法,分别表示绑定成功与断开;
  3. 并将 connection 传递给 bindService() 方法去启动 Service;
  4. 在ServiceConnection的onServiceConnected()方法里启动 MyService 里的方法。
  5. 最后通过 unbindService 来解绑服务。

5.IntentService是什么?

IntentService是Service的子类,是一个异步的、会自动停止的服务,很好解决了传统的Service中处理完耗时操作忘记停止并销毁Service的问题。


6.说说 Activity、Intent 和 Service 是什么关系

他们都是 Android 开发中使用频率最高的类。其中 Activity 和 Service 都是 Android 四大组件之一。他俩都是 Context 类的子类 ContextWrapper 的子类,因此他俩可以算是兄弟关系吧。不过兄弟俩各有各自的本领,Activity 负责用户界面的显示和交互,Service 负责后台任务的处理。Activity 和 Service 之间可以通过 Intent 传递数据,因此可以把 Intent 看作是通信使者。


7.如何保证Service不被杀死?(就是提高Service优先级)


8.Service 和 BroadcastReceiver 共同点


9.Service 里面可以弹吐司么

可以的,Service不仅可以弹Toast还能弹出对话框,第一,Service是运行在主线程当中;第二,弹吐司有个条件就是得有一个 Context 上下文,而 Service 本身就是 Context 的子类;因此在 Service 里面弹吐司是完全可以的。


10.是否能在Service进行耗时操作?如果非要可以怎么做?

Service默认运行在主线程中,所以不能在Service里执行耗时操作,除非手动打开一个子线程,否则有可能出现主线程被阻塞(ANR)的情况。(开启子线程的方法有:继承、实现、匿名类) ,但我更建议使用IntentService来代替,因为它是一个异步的、会自动停止的Service服务。


11.一个Activty先start一个Service后,再bind时会回调什么方法?此时如何做才能回调Service的destory()方法?

当对一个服务既调用 startService() 方法,又调用了bindService()方法,根据Android系统的机制,一个服务只要被启动或者被绑定了之后,就会一直处于运行状态,必须要让以上两种条件同时不满足,服务才能被销毁。所以,这种情况要同时调用是stopService()和unbindService方法,onDestroy才会执行。


12.前台服务是什么?和普通服务的不同?如何去开启一个前台服务?

前台服务和普通服务最大的区别是:前者会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。使用前台服务或者为了防止服务被回收掉,比如听歌,或者由于特殊的需求,比如实时天气状况。

想要实现一个前台服务非常简单,它和之前学过的发送一个通知非常类似,只不过在构建好一个Notification之后,不需要NotificationManager将通知显示出来,而是调用了startForeground()方法。

//修改MyService的onCreate()方法:
public void onCreate(){
        Intent intent = new Intent(this,MainActivity.class);
        PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("This is content title")
                .setContentText("This is content text")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                .setContentIntent(pi)
                .build();
        startForeground(1,notification);
}

13.是否了解ActivityManagerService,谈谈它发挥什么作用?

ActivityManagerService是Android中最核心的服务 , 主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块类似。


14.用过哪些系统Service?

系统服务

15.AlarmManager能实现定时的原理?

通过调用AlarmManager的 set() 方法就可以设置一个定时任务,并提供三个参数(工作类型,定时任务触发的时间,PendingIntent对象)。其中第三个PendingIntent对象是关键,一般会调用它的 getBroadcast() 方法来获取一个能够执行广播的PendingIntent。这样当定时任务被触发的时候,广播接收器的onReceive()方法就可以得到执行。即通过服务和广播的循环触发实现定时服务。


16.Service 和 Thread 的区别


17.开启子线程的方法

// 1、新建类继承自Thread,然后重写父类的run方法,并在里面编写耗时逻辑。
class MyThread extends Thread{
    public void run(){
    }
}
new MyThread().start();
// 2、实现Runnable接口可以降低继承的耦合性
class MyThread implements Runnable{
    public void run(){
    }
}
MyThread my = new MyThread();
new Thread(my).start();
// 3、使用匿名类的方式,这种方式最常见
new Thread(new Runnable(){
    public void run(){
    }
}).start()

18.Service 的 onStartCommand 方法有几种返回值?各代表什么意思?

有四种返回值,不同值代表的意思如下:


你一般在什么情况下会使用Service?

当需要长期在后台进行的工作我们需要将其放在Service中去做,比如音乐播放、下载、上传大文件、定时关闭应用等功能。这样做的原因是如果放在Activity当中去执行的话,当Activity销毁后,那这些功能也就停止了,这显然是不符合我们的设计要求的,所以要将他们放在Service中去执行。


了解Binder机制

https://www.jianshu.com/p/da76ffa0c859


本文参考资料:

上一篇 下一篇

猜你喜欢

热点阅读