Androidc Learning Notes 7 Service Service

Keywords: Android xml encoding Java

Service Service Development and Understanding in android

Records of 2017/3/13

Service Services of Four Components

Services do not run in a separate process, but depend on the application process in which they are created.
Service: It is a solution to realize the background running of the program in android. It is well suited for tasks that do not require long-term user interaction.
And in fact, services do not automatically open threads. All service codes run on the main thread, so we need to create sub-threads manually.


Inheritance: Implement the runable interface directly or inherit the Thread parent class (in the subthread run method) to start the start() thread.
Inheritance mode: New MyThread().start(); Implementation interface method: new Thread(MyThread).start();


Like many UI libraries. android's UI library is also thread insecure, so you want to update UI elements in your application.
It must be done in the main thread, otherwise an exception will occur.
Let's write a small example to see.
activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.ldp.com.androidthreadtest.MainActivity">


    <Button
        android:id="@+id/change_text"
        android:text="Change Text"
        android:textAllCaps="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text"
        android:layout_centerInParent="true"
        android:textSize="20sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>


MainActivity
package com.example.ldp.com.androidthreadtest;


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {


    private TextView text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView)findViewById(R.id.text);
        Button button = (Button)findViewById(R.id.change_text);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        text.setText("Nice to meet you");
                    }
                }).start();
            }
        });
    }
}

Design sketch:


It can be solved by updating UI with the usage of asynchronous message processing in android.
Change the code: MainActivity
package com.example.ldp.com.androidthreadtest;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {


    public static final int UPDATE_TEXT=1;
    private TextView text;


    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                //In this way, multiple asynchronous messages can be implemented to update the UI.
                case UPDATE_TEXT:
                    text.setText("Nice to meet you");
                    break;
                default:
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView)findViewById(R.id.text);
        Button button = (Button)findViewById(R.id.change_text);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //Call with Message Object
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        handler.sendMessage(message);
                    }
                }).start();
            }
        });
    }
}

If you run it again, you will see that UI operations are not performed in the sub-threads, but only a Message object is created.
Pass this object to handle and handle it with handleMessage(), which in this case allows the operation to run in the main thread rather than in the sub-thread.

Resolve the asynchronous message mechanism:
It is divided into four parts: Message, Handle, MessafeQueue, Looper
Message: Used to pass messages between threads or to send shaping data
handler: Processor for sending and processing messages. sendMessage() handleMessage()
MessageQueue: Message queue in which messages sent by Handler are stored will always exist, and there will only be one MessageQueue object per thread.
Looper: is the steward of MessageQueue in each thread. After calling the loop() method, it will go into the wireless loops to find messages and find the handleMessage(), and there will only be one Looper object in each thread.
Design sketch:
               

AsyncTask, another tool provided in android, can be learned if the above steps are troublesome.
Of course, the steps are much simpler.

Basic and Usage of Services:
A new service service class can be created directly on the project. We need to inherit the service class and implement several methods.
Note: Services need to be registered in AndroidManifast.xml
For example, create a new MyService class and modify it on the last asynchronous messaging mechanism project
package com.example.ldp.com.androidthreadtest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;


public class MyService extends Service {
    public MyService() {
    }


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }


    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","OnCreat Method Start");
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService","onStartCommand Method Start");
        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyService","onDestroy Method Start");
    }
}

activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <Button
        android:id="@+id/change_text"
        android:text="Change Text"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/start_service"
        android:text="Start Service"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/stop_service"
        android:text="Stop Service"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text"
        android:layout_centerInParent="false"
        android:textSize="20sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</LinearLayout>


MainActivity.java
package com.example.ldp.com.androidthreadtest;


import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{


    public static final int UPDATE_TEXT=1;
    private TextView text;


    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                //In this way, multiple asynchronous messages can be implemented to update the UI.
                case UPDATE_TEXT:
                    text.setText("Nice to meet you");
                    break;
                default:
                    break;
            }
        }
    };




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);




        text = (TextView)findViewById(R.id.text);
        Button button = (Button)findViewById(R.id.change_text);
        Button startButton = (Button)findViewById(R.id.start_service);
        Button stopButton = (Button)findViewById(R.id.stop_service);
        startButton.setOnClickListener(this);
        stopButton.setOnClickListener(this);
        button.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.change_text:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //Call with Message Object
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        handler.sendMessage(message);
                    }
                }).start();
                break;
            case R.id.start_service:
                Intent startIntent = new Intent(this,MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntrnt = new Intent(this,MyService.class);
                stopService(stopIntrnt);
                break;
            default:
                break;
        }
    }
}


The rendering shows that the oncreat e method and onStartCommand method are executed by clicking on startService, but only the onStartCommand method is executed by clicking several times.
Click Stop to Execute onDestory Method
Design sketch:


Has it been found that we notify the service through activities that can be performed? There is no use for activity.

Service life cycle
Design sketch:
                

For example, weather software, when used, will display the weather status in the status bar, which is an application of the front desk service.
Modified example in the previous example: MyService
 
@Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","OnCreat Method Start");
        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 ")
                .setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                .setContentIntent(pi).build();
        startForeground(1,notification);
    }

Design sketch:
                                             

Note that if a large number of logical code processing is written in the service, it is likely that ANR(Application Not Response) will occur in the application.
So a standard service should be written as MyService
 
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService","onStartCommand Method Start");
        new Thread(new Runnable() {
            @Override
            public void run() {
                //Concrete logic realization
                stopSelf();//The purpose of stopping service here is to avoid running all the time. It can also be written as stopService().
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

In the beginning process, it is often forgotten to open the thread or call the stop service, which causes the program to have problems, so it is provided in android.
IntentService parent class
package com.example.ldp.com.androidthreadtest;


import android.app.IntentService;
import android.content.Intent;
import android.util.Log;


/**
 * Created by Administrator on 2017/3/13.
 */


public class MyIntentService extends IntentService {


    public MyIntentService(){
        super("MyIntentService");//Call the constructor of the parent class
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        //Implementing logic without worrying about ARN
        Log.d("MyIntentService","Thread is "+Thread.currentThread().getId());
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyIntentService","OnDestory Method");
    }
}

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <Button
        android:id="@+id/change_text"
        android:text="Change Text"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/start_service"
        android:text="Start Service"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/
stop_service"
        android:text="Stop Service"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/myintent_service_start"
        android:text="Start MyIntent Service"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


    <TextView
        android:id="@+id/text"
        android:layout_centerInParent="false"
        android:textSize="20sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</LinearLayout>


Register services in AndroidManfest.xml
  <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">
        </service>
        <service android:name=".MyIntentService"/>

MyService.java remains unchanged


MainActivity.java 		
package com.example.ldp.com.androidthreadtest;


import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{


    public static final int UPDATE_TEXT=1;
    private TextView text;


    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                //In this way, multiple asynchronous messages can be implemented to update the UI.
                case UPDATE_TEXT:
                    text.setText("Nice to meet you");
                    break;
                default:
                    break;
            }
        }
    };




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);




        text = (TextView)findViewById(R.id.text);
        Button button = (Button)findViewById(R.id.change_text);
        Button startButton = (Button)findViewById(R.id.start_service);
        Button stopButton = (Button)findViewById(R.id.stop_service);
        Button myintetnbutton = (Button)findViewById(R.id.myintent_service_start);
        myintetnbutton.setOnClickListener(this);
        startButton.setOnClickListener(this);
        stopButton.setOnClickListener(this);
        button.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.change_text:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //Call with Message Object
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        handler.sendMessage(message);
                    }
                }).start();
                break;
            case R.id.start_service:
                Intent startIntent = new Intent(this,MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntrnt = new Intent(this,MyService.class);
                stopService(stopIntrnt);
                break;
            case R.id.myintent_service_start:
                Log.d("MainActivity","Thread is "+Thread.currentThread().getId());
                Intent intentService = new Intent(this,MyIntentService.class);
                startService(intentService);
                break;
            default:
                break;
        }
    }
}




Design sketch:



Let's do an example of what we learned before a collection:

Posted by gethinw on Wed, 17 Apr 2019 22:45:33 -0700