Android service (1)

Service as one of the four components of Android, in every application plays a very important role. It is mainly used in the background to deal with some time-consuming logic, or to perform some of the tasks that require long-term operation. When necessary, we can even exit the program in the case, so that Service in the background to keep running.

Basic usage of Service

Service on the most basic usage is how to start a Service, and start the Service method and start the Activity is very similar, need to use Intent to achieve, the following we through a specific example to look at.

Create a new Android project, the project name is called MyService Project, where I chose to use the 4.0 API.

And then create a new service inherited from the Service, and rewrite the parent class onCreate (), onStartCommand () and onDestroy () method, as follows:

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  
      
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        return null;  
    }  
  
}  

You can see that we just printed a word in the onCreate (), onStartCommand (), and onDestroy () methods, and did nothing else.

And then open or create activity_main.xml as the main layout file for the program, as follows:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical" >  
  
    <Button  
        android:id="@+id/start_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Start Service" />  
  
    <Button  
        android:id="@+id/stop_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Stop Service" />  
  
</LinearLayout> 

We added two buttons in the layout file, one for starting Service, one for stopping Service. And then open or create a MainActivity as the main activity of the program, in which to join the Start Service and stop the Service logic, the code is as follows:

public class MainActivity extends Activity implements OnClickListener {  
  
    private Button startService;  
  
    private Button stopService;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        startService = (Button) findViewById(R.id.start_service);  
        stopService = (Button) findViewById(R.id.stop_service);  
        startService.setOnClickListener(this);  
        stopService.setOnClickListener(this);  
    }  
  
    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.start_service:  
            Intent startIntent = new Intent(this, MyService.class);  
            startService(startIntent);  
            break;  
        case R.id.stop_service:  
            Intent stopIntent = new Intent(this, MyService.class);  
            stopService(stopIntent);  
            break;  
        default:  
            break;  
        }  
    }  
  
}  

You can see that in the click event of the Start Service button, we build an Intent object and call the startService () method to start MyService. Then in the Stop Serivce button’s click event, we also constructed an Intent object and called the stopService () method to stop MyService. Code logic is very simple, I believe I do not need to do more to explain it.

Also note that every service in the project must be registered in the AndroidManifest.xml, so you need to edit the AndroidManifest.xml file, the code is as follows:

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="com.example.servicetest"  
    android:versionCode="1"  
    android:versionName="1.0" >  
  
    <uses-sdk  
        android:minSdkVersion="14"  
        android:targetSdkVersion="17" />  
  
    <application  
        android:allowBackup="true"  
        android:icon="@drawable/ic_launcher"  
        android:label="@string/app_name"  
        android:theme="@style/AppTheme" >  
          
    ……  
  
        <service android:name="com.example.servicetest.MyService" >  
        </service>  
    </application>  
  
</manifest>

In this case, a simple program with Service function is written, and now we will run the program, and click the Start Service button, you can see LogCat print log.

You will see that when you start a Service, it will call the Service onCreate () and onStartCommand () method.

So what if I click on the Start Service button again?

You can see that this time only onStartCommand () method is implemented, onCreate () method is not implemented, why is this? This is because the onCreate () method will only be called when the Service is first created. If the current Service has already been created, the onCreate () method will not be executed anyway, regardless of how the startService () method is called. So you can click on the Start Service button several more times, each time there will only be onStartCommand () method in the print log.

We can also go to the phone’s application management interface to check myService is not running.

Go back to the ServiceTest program and click the Stop Service button to stop MyService.

Service and Activity communication

Above we learned the basic usage of the Service, after starting Service, you can in the onCreate () or onStartCommand () method to perform some specific logic. But then the relationship between Service and Activity is not large, but Activity notice Service about: “You can start.” Then Service to busy their own things. Then there is no way to make the two of them more related to it? For example, in the Activity can be specified to allow Service to perform what task. Of course, only need to make Activity and Service to establish a link just fine.

Observe the code in MyService, you will find that there is always an onBind () method we have not used, this method is used to establish association with the Activity, modify the code in MyService, as follows:

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    private MyBinder mBinder = new MyBinder();  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  
  
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        return mBinder;  
    }  
  
    class MyBinder extends Binder {  
  
        public void startDownload() {  
            Log.d("TAG", "startDownload() executed");  
            // Perform a specific download task
        }  
  
    }  
  
}  

Here we add a MyBinder class inherited from the Binder class, and then add a MyBinder startDownload () method used to perform the download task in the background, of course, here is not really to download something, just a test, so The startDownload () method simply prints a row of logs.

And then modify the code in activity_main.xml to add buttons for binding services and unbind services in the layout file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical" >  
  
    <Button  
        android:id="@+id/start_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Start Service" />  
  
    <Button  
        android:id="@+id/stop_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Stop Service" />  
  
    <Button  
        android:id="@+id/bind_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Bind Service" />  
      
    <Button   
        android:id="@+id/unbind_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Unbind Service"  
        />  
      
</LinearLayout> 

Next, modify the code in MainActivity to associate the MainActivity and MyService with the following code:

public class MainActivity extends Activity implements OnClickListener {  
  
    private Button startService;  
  
    private Button stopService;  
  
    private Button bindService;  
  
    private Button unbindService;  
  
    private MyService.MyBinder myBinder;  
  
    private ServiceConnection connection = new ServiceConnection() {  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  
  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            myBinder = (MyService.MyBinder) service;  
            myBinder.startDownload();  
        }  
    };  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        startService = (Button) findViewById(R.id.start_service);  
        stopService = (Button) findViewById(R.id.stop_service);  
        bindService = (Button) findViewById(R.id.bind_service);  
        unbindService = (Button) findViewById(R.id.unbind_service);  
        startService.setOnClickListener(this);  
        stopService.setOnClickListener(this);  
        bindService.setOnClickListener(this);  
        unbindService.setOnClickListener(this);  
    }  
  
    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.start_service:  
            Intent startIntent = new Intent(this, MyService.class);  
            startService(startIntent);  
            break;  
        case R.id.stop_service:  
            Intent stopIntent = new Intent(this, MyService.class);  
            stopService(stopIntent);  
            break;  
        case R.id.bind_service:  
            Intent bindIntent = new Intent(this, MyService.class);  
            bindService(bindIntent, connection, BIND_AUTO_CREATE);  
            break;  
        case R.id.unbind_service:  
            unbindService(connection);  
            break;  
        default:  
            break;  
        }  
    }  
  
}  

You can see that here we first create an anonymous class of ServiceConnection, which rewrites the onServiceConnected () method and the onServiceDisconnected () method, which are invoked when the Activity is associated with the service and associated with the service. In the onServiceConnected () method, we have passed down to get an instance of MyBinder. With this example, the relationship between Activity and Service becomes very tight. Now we can in the Activity in accordance with the specific scene to call MyBinder in any public method, that is, to achieve the Activity Command Service Service What to do what function.

Of course, now Activity and Service is not linked to it, this feature is in the Bind Service button to complete the click event. You can see that here we are still building an Intent object, and then call the bindService () method to bind the Activity and Service. BindService () method to receive three parameters, the first parameter is just to build the Intent object, the second parameter is created in front of the ServiceConnection instance, the third parameter is a flag, where the incoming BIND_AUTO_CREATE said in the Activity And Service established after the association automatically create Service, which will make MyService onCreate () method to be implemented, but onStartCommand () method will not be implemented.

And then how do we want to relieve the association between Activity and Service? Call the unbindService () method on it, this is the Unbind Service button click event to achieve the logic.

Now let’s run the program again, click on the Bind Service button in MainActivity.

Also note that any Service is generic across the entire application, that is, MyService can not only be associated with MainActivity, but also can be associated with any of the activities, and in the establishment of the association they can get to the same MyBinder instance.

How to destroy Service

In this part of the basic usage of Service, we introduced the simplest case of Destroy Service, click the Start Service button to start Service, and then click the Stop Service button to stop Service, so MyService was destroyed.

So if we are clicking on the Bind Service button? Because the binding service when the designated bit is BIND_AUTO_CREATE, indicating that the Bind Service button when the Service will be created, then how should destroy the Service? In fact, it is very simple, click on the Unbind Service button, the association between the Activity and Service can be lifted.

The above two kinds of destruction methods are well understood. So what if we both clicked the Start Service button and clicked on the Bind Service button? This time you will find that, whether you are a single click on the Stop Service button or Unbind Service button, Service will not be destroyed, the need to click the two buttons, Service will be destroyed. In other words, click the Stop Service button will only stop the Service, click the Unbind Service button will only let Service and Activity release association, a Service must be in any and no association and deal with the stop state will be destroyed.

To confirm that we add a line of print log to the Stop Service and Bindservice button’s click event:

public void onClick(View v) {  
    switch (v.getId()) {  
    case R.id.start_service:  
        Intent startIntent = new Intent(this, MyService.class);  
        startService(startIntent);  
        break;  
    case R.id.stop_service:  
        Log.d("MyService", "click Stop Service button");  
        Intent stopIntent = new Intent(this, MyService.class);  
        stopService(stopIntent);  
        break;  
    case R.id.bind_service:  
        Intent bindIntent = new Intent(this, MyService.class);  
        bindService(bindIntent, connection, BIND_AUTO_CREATE);  
        break;  
    case R.id.unbind_service:  
        Log.d("MyService", "click Unbind Service button");  
        unbindService(connection);  
        break;  
    default:  
        break;  
    }  
}  

And then re-run the program, first click the Start Service button, and then click the Bind Service button, so the service will start up, and the establishment of an association with the Activity. And then click the Stop Service button Service will not be destroyed, and then click the Unbind Service button, Service will be destroyed.

We should always remember in the Service’s onDestroy () method to clean up those no longer use the resources to prevent the Service is destroyed after some of the objects are no longer occupied by the memory.

The relationship between Service and Thread

Many Android beginners may have such doubts, Service and Thread in the end what is the relationship? When should I use Service, when should I use Thread? The answer may be a bit surprised you, because there is no relationship between Service and Thread!

The reason why many people will link them up, mainly because the background of Service background. Thread we all know that is used to open a sub-thread, here to perform some time-consuming operation will not block the main thread of the operation. And Service we initially understand, always think it is used to deal with some background tasks, some of the more time-consuming operation can also be placed here to run, which will make people confused. But if i tell you that Service is actually running in the main thread, do you think it has anything to do with Thread? Let’s take a look at this cruel fact.

In the MainActivity onCreate () method to add a line to print the current thread id statement:

Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());  

And then in the MyService onCreate () method also joined a line to print the current thread id statement:

Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());  

Now re-run the program and click the Start Service button.

You can see that their thread id is exactly the same, which confirmed that the service is indeed running in the main thread, that is, if you are in the Service prepared a very time-consuming code, the program will appear ANR.

Can you exclaim, is not that kidding? What time do I have to use Service? In fact, we should not background and sub-thread together on the line, this is two completely different concepts. Android background means that it’s running is completely dependent on the UI. Even if Activity is destroyed, or the program is closed, as long as the process is still, Service can continue to run. For example, some applications, always need to always maintain a heartbeat connection with the server, you can use Service to achieve. You may ask, the front is not just verified Service is running in the main thread Lane? Where the implementation of the heartbeat has been connected, do not block the main thread of the operation? Of course, but we can create a sub-thread in the service, and then here to deal with time-consuming logic no problem.

Create Front Service

The amount, since in the service also to create a sub-thread, then why not directly created in the Activity? This is because the Activity is difficult to control the Thread, when the Activity is destroyed, there is no other way to re-get to the previously created sub-thread instance. But also in an Activity to create a sub-thread, another Activity can not operate on it. But the Service is different, all the Activity can be associated with the Service, and then can be very convenient to operate the method, even if the Activity was destroyed, and then as long as the re-established with the Service, they can get to the original Service Example of Binder. Therefore, the use of Service to deal with background tasks, Activity can be assured to finish, do not need to worry about the background tasks can not control the situation.

A more standard service can be written as:

@Override  
public int onStartCommand(Intent intent, int flags, int startId) {  
    new Thread(new Runnable() {  
        @Override  
        public void run() {  
            // Start performing background tasks
        }  
    }).start();  
    return super.onStartCommand(intent, flags, startId);  
}  
  
class MyBinder extends Binder {  
  
    public void startDownload() {  
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                // Perform a specific download task
            }  
        }).start();  
    }  
  
}  

Then we look at how to create a front desk Service it, in fact, not complicated, modify the code in MyService, as follows:

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    private MyBinder mBinder = new MyBinder();  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Notification notification = new Notification(R.drawable.ic_launcher,  
                "There is a notice coming", System.currentTimeMillis());  
        Intent notificationIntent = new Intent(this, MainActivity.class);  
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,  
                notificationIntent, 0);  
        notification.setLatestEventInfo(this, "This is the title of the notification", "This is the content of the notice",  
                pendingIntent);  
        startForeground(1, notification);  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    .........  
  
}  

Here is only modify the MyService onCreate () method code. You can see that we first created a Notification object and then called its setLatestEventInfo () method to initialize the layout and data for the notification, and set the click notification to open the MainActivity. And then call the startForeground () method can make MyService into a front service, and will notify the image displayed.

Now run the program again, and click the Start Service or Bind Service button, MyService will be the front service mode to start, and the system status bar will pop up a bar icon, drop the status bar can see the details of the notice.

Advertisements

One thought on “Android service (1)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s