Service服务-Android

Posted hequnwang10

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Service服务-Android相关的知识,希望对你有一定的参考价值。

  1. Service既不是一个线程,Service通常运行在当成宿主进程的主线程中,所以在Service中进行一些耗时操作就需要在Service内部开启线程去操作,否则会引发ANR异常。
  2. 也不是一个单独的进程。除非在清单文件中声明时指定进程名,否则Service所在进程就是application所在进程。

Service默认线程为UI线程,不要在Service中执行耗时的操作,除非你在Service中创建了子线程来完成耗时操作。

一、用法

1、启动方式:

  1. startService()
  2. bindService()
  3. 同时调用


接下来用这三个文件展示startService和bindService使用,直接给出代码:

activity_service.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="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=".ServiceDemo.ServiceActivity">

    <Button
        android:id="@+id/startService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开启Service"
        android:onClick="startService"
        android:textAllCaps="false"
        android:textSize="22sp"
        />

    <Button
        android:id="@+id/shutdownService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="关闭Service"
        android:onClick="shutdownService"
        android:textAllCaps="false"
        android:textSize="22sp"
        />

    <Button
        android:id="@+id/bindService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind开启Service"
        android:onClick="bindService"
        android:textAllCaps="false"
        android:textSize="22sp"
        />

    <Button
        android:id="@+id/unbinddownService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind关闭Service"
        android:onClick="unbindService"
        android:textAllCaps="false"
        android:textSize="22sp"
        />

</LinearLayout>

MyBind.java

public class MyBind extends Binder 
    private static final String TAG = "MyBind";

    public void show()
        Log.i(TAG, "show: ");
    

MyService.java

public class MyService extends Service 
    private static final String TAG = "MyService";

    public MyService() 
    

    @Override
    public void onCreate() 
        super.onCreate();
        Log.i(TAG, "onCreate: ");
    


    @Override
    public IBinder onBind(Intent intent) 
        // TODO: Return the communication channel to the service.
        Log.i(TAG, "onBind: ");
        return new MyBind();
    

    @Override
    public boolean onUnbind(Intent intent) 
        Log.i(TAG, "onUnbind: ");
        return super.onUnbind(intent);
    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        Log.i(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    

    @Override
    public void onDestroy() 
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
    

ServiceActivity.java

public class ServiceActivity extends AppCompatActivity 
    private static final String TAG = "ServiceActivity";

    private Button startService;
    private Button shutdownService;
    private Button bindService;
    private Button unbinddownService;
    private Intent intent;
    private ServiceConnection serviceConnection;
    private MyBind myBind;

    public ServiceActivity() 
    

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        initView();
        initData();
    

    private void initData() 
        serviceConnection = new ServiceConnection() 
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) 

                myBind = new MyBind();
                myBind.show();
                Log.i(TAG, "onServiceConnected: ");
            

            @Override
            public void onServiceDisconnected(ComponentName name) 
                Log.i(TAG, "onServiceDisconnected: ");

            
        ;
    

    private void initView() 
        startService = (Button) findViewById(R.id.startService);
        shutdownService = (Button) findViewById(R.id.shutdownService);
        bindService = (Button) findViewById(R.id.bindService);
        unbinddownService = (Button) findViewById(R.id.unbinddownService);

        intent = new Intent(ServiceActivity.this, MyService.class);
    

    public void startService(View view) 
        startService.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                startService(intent);
            
        );
    

    public void shutdownService(View view) 
        shutdownService.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                stopService(intent);
            
        );

    

    public void bindService(View view) 
        bindService.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
            
        );
    

    public void unbindService(View view) 
        unbinddownService.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                unbindService(serviceConnection);
            
        );
    

startService()

bindService()

当同时调用startService和bindService后,需要分别调用stopService和unbindService,Service才会走onDestroy()
一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁

二、前台Service

Service几乎都是在后台运行的,一直以来它都是默默地做着辛苦的工作。但是Service的系统优先级还是比较低的,当系统出现内存不足情况时,就有可能会回收掉正在后台运行的Service。如果你希望Service可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,就可以考虑使用前台Service。前台Service和普通Service最大的区别就在于,它会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。当然有时候你也可能不仅仅是为了防止Service被回收才使用前台Service,有些项目由于特殊的需求会要求必须使用前台Service.

三、IntentService

通过StartService形式开启Service时,如果不主动调用stopService,Service将在后台一直运行。同时如果我们在Service中执行耗时操作还是引起ANR异常,为了解决这2个问题,IntentService出现了。
当我们需要执行某些一次性、异步的操作时,IntentService能很好的满足这个场景。

IntentService相比于普通的Service,在使用时将不再需要实现onStartCommand(),同时需要实现onHandleIntent()。
真正需要我们处理的逻辑就在onHandleIntent()实现,IntentService会内部自动调用stopSelf()关闭自己。
至于防止ANR异常,具体的实现方式其实还是挺简单,就是在内部新建了子线程,并在子线程中内部的Looper来分发事件。

以上是关于Service服务-Android的主要内容,如果未能解决你的问题,请参考以下文章

从零开始怎么写android native service?

从零开始怎么写android native service?

Android:两个独立 APK 的两个服务之间的通信

如何从 android SERVICE 禁用/启用屏幕旋转?

android Service在8.0以及通知栏不显示的问题

android Service在8.0以及通知栏不显示的问题