Android learning notes Service

Posted by mrtechguy on Thu, 06 Jan 2022 12:21:58 +0100

Service runs in the background of the program

Service

Service is a subclass of Context

UI controls are thread unsafe. All UI operations must be in the main thread

Service does not automatically start the thread. All codes run in the main thread by default. You should manually start the sub thread

The IntentService opened in the service is more important than the AsyncTask opened in the activity and is less likely to be killed

Service usage

Right click New → Service → Service

The Export property indicates whether other programs are allowed to access the Service

The Enabled property indicates whether the Service is Enabled

At any location, you can call the stopSelf() method to stop the Service

Common use

Start Service

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

End Service

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

Bind to Activity

public class MyService extends Service {
​
    class MyBinder extends Binder{
        public void startSomething(){
            ...//You can open IntentService here
        }
    }
​
    public MyService() { }
​
    @Override
    public void onCreate() {
        super.onCreate();
    }
​
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
​
    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();//By exposing the connector to the outside, the activity can use the methods in the connector to execute in the Service
    }
​
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

Use ServiceConnection in the activity to get the connector returned by the Service

It realizes the function of commanding services to do whatever services they do

private ServiceConnection connection=new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MyService.MyBinder myBinder=(MyService.MyBinder) service;//Get connector
        myBinder.startSomething();//Execute the methods in the connector
    }
​
    @Override
    public void onServiceDisconnected(ComponentName name) { }
};

Start binding

Intent intent=new Intent(this,MyService.class);
bindService(intent,connection,BIND_AUTO_CREATE);//Bind to a specific service in the background through ServiceConnection

End binding

unbindService(connection);

Service Lifecycle

If the Service in the process is executing the life cycle callback, the process belongs to the foreground process

If the Service in the process is bound to the activity currently in the foreground, the process belongs to the foreground process

Start using startService()

Oncreate() - > onstartcommand() - > stopservice() / stopSelf() is executed only for the first startup, and onDestroy() is executed

  • Suitable for long-term execution of a task

  • Whether or not an Activity uses bindService()/unbindService() to the Service, the Service runs in the background until stopService() / stopSelf() is called

  • No matter how many times startService() is used, stopservice () will stop the service once

  • After the Service is started, it has nothing to do with the Activity. It is not required to manually exit the Service when the Activity exits

Start using bindService()

Oncreate() - > onbind() - > unbindservice() is executed only the first time, then onunbind() - > ondestroy() is executed

  • It is suitable for contacting the running Service / similar lazy thinking. Don't create it first. bind it when you need it to save resources

  • The Service runs in the background until unbindService() is called to unbind / bind the Service, and the Context does not exist

  • The Service life cycle is attached to the Context that started it. Therefore, after the Context of the current station calling bindService() is destroyed, the Service will automatically call onUnbind() and onDestory()

Start using hybrid mode

The Service is called by startservice () and bindservice (). The Service will always run in the background. No matter how many times it is called, onCreate() method will always be called only once. The number of calls to onStartCommand() is the same as that of startService() (onStartCommand() will not be called using bindService() method). At the same time, calling unBindService() will not stop the Service. You must call stopService() or stopSelf() of the Service itself to stop the Service

Front desk Service

8.0+Service will be recycled by the system at any time when running in the background. The Service can run stably only when the application foreground is visible (in the form of similar notification)

Once the channel is established, modifying the channel attribute will no longer take effect unless the channel id is uninstalled and reinstalled / changed

9.0 + need to add a common permission

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

In the onCreate() method of the Service

@Override
    public void onCreate() {
        super.onCreate();
​
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("foreground", "Reception Service", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
        }
        
        Intent intent = new Intent(this, MainActivity.class);
        //Here, you can also use taskStackBuilder to obtain pendingIntent
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        
        //compat can be compatible with all Android versions. The parameters are (context, channel id)
        Notification notification= new NotificationCompat.Builder(this,"foreground")
            .setContentTitle("Notice title")
            .setContentText("Notice content")
            .setSmallIcon(R.drawable.xxx)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.xxx))//Parse picture into Bitmap
            .setShowWhen(false)//Show time
            .setNotificationSilent()//Silent notification
            .setVisibility(NotificationCompat.VISIBILITY_SECRET)//Lock screen not visible
            .setContentIntent(pending)//Click the notification to jump to the page
            .build();//Create notification object
​
        //Note that the way to start the notification is not to send the notification through the manager, but to start the foreground
        startForeground(1, notification);
    }

cancel

  • Reducing the foreground service to the background service can make it disappear from the taskbar

//The service does not stop until stopService() is called
stopForeground(true);
  • Directly stop Service (), regardless of whether the Service is in the front / background, it will end directly

IntentService

Is a subclass of Service

Service itself is running in the main thread. If the execution time consuming operation needs to manually open the child thread and stop stopSelf or stopService after the end of the operation, it is feasible, but it is not a good choice to manage the Service life cycle and Zi Xiancheng, so android provides IntentService to realize the automatic opening of the sub thread and close it.

Create a new class that inherits IntentService

public class MyIntentService extends IntentService {
​
    public MyIntentService() {
        super("MyIntentService");
    }
​
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        //This method is already running in a child thread and can handle some time-consuming logic
    }
}

usage method

Intent intent=new Intent(this,MyIntentService.class);
startService(intent);

Since it is a Service, you need to register in the Manifest file

<service
        android:name=".MyIntentService"
        android:enabled="true"
        android:exported="true" />

Topics: Java Android UI