1. 程式人生 > >Service 定義(startService、bindService、IntentService)

Service 定義(startService、bindService、IntentService)

Service:

是Android中實現程式後臺執行的解決方案。
定義為服務
Service預設並不會執行在子執行緒中,它也不會執行在一個獨立的程序中,它同樣執行在UI執行緒中,因此,不要在Service中執行耗時的操作,如果需要執行耗時的操作,可以在Service中建立子執行緒來完成耗時操作。

什麼是手機病毒?

手機病毒是編制者在手機程式中插入帶破壞資料。吸費。監控等功能的程式碼,能影響手機使用,能自我複製的一組指令或者程式程式碼。
病毒的共性是擁有潛伏性,觸發性,傳染性,破壞性。
病毒都是偷偷的在後臺執行預設的功能。

為什麼要用Service?

大部分病毒利用Service的特點,可以不知不覺(後臺)完成預設的功能。
作為Android工程師,至少需要了解Service是如何在後臺完成預設功能。
在真實的商業專案中都有定期在後臺執行任務(如:下載,上傳等)的需求。
當某個功能需要執行很長時間(如:下載,收集資料等),並且在執行過程中不需要讓使用者操作,不需要Activity進行互動的情況下,可以通過Service在後臺完成指定任務。

Service有幾種啟動模式?
有兩種啟動模式:

startService()啟動方式:主要用於執行後臺計算
bindService()啟動方式:主要用於和其它元件的互動

startService的特點及優缺點?

Service會經歷 onCreate –> onStart stopService的時候直接onDestroy
如果是 呼叫者直接退出而沒有呼叫stopService的話,Service會一直在後臺執行。 下次呼叫者再起來仍然可以stopService。

bindService 的特點及優缺點?

Service只會執行onCreate, 這個時候 呼叫者和Service繫結在一起

呼叫者退出了,Srevice就會呼叫onUnbind–>onDestroyed 所謂繫結在一起就共存亡了。

兩者放在一塊的程式碼演示:

package com.example.myapplication15;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_start;
private Button btn_end;
private Button bind;
private Button unbind;
private Button main;

    private MyService.DownloadBinder downloadBinder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            downloadBinder = (MyService.DownloadBinder) iBinder;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };




    DownLoadBinder downLoadBinder=new DownLoadBinder();


    public class DownLoadBinder extends Binder{
       public void startDownload(){}


   }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_start=findViewById(R.id.btn_start);
        btn_end=findViewById(R.id.btn_end);
        btn_start.setOnClickListener(this);
        btn_end.setOnClickListener(this);
        bind = findViewById(R.id.main_bind);
        unbind = findViewById(R.id.main_unbind);
        bind.setOnClickListener(this);
        unbind.setOnClickListener(this);
        main=findViewById(R.id.main2_btn);
        main.setOnClickListener(this);
    }


    @Override
    public void onClick(View view) {
      switch (view.getId()){
          case R.id.main_bind:
              Intent bindIntent = new Intent(this, MyService.class);
              bindService(bindIntent, connection, BIND_AUTO_CREATE);
              break;
          case R.id.main_unbind:
              unbindService(connection);
              break;
          case  R.id.btn_start:
              Intent statintent=new Intent(MainActivity.this,MyService.class);
             startService(statintent);
              break;
          case R.id.btn_end:
              Intent endintent=new Intent(MainActivity.this,MyService.class);
              stopService(endintent);
              break;
          case  R.id.main2_btn:
              Intent intent=new Intent(MainActivity.this,Main2Activity.class);
              startActivity(intent);
          default:
              break;
      }
    }
}

佈局檔案:

<?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="com.example.myapplication15.MainActivity">

    <Button
        android:text="開始"
        android:layout_marginTop="50dp"
        android:id="@+id/btn_start"
        android:layout_gravity="center"
        android:layout_width="80dp"
        android:layout_height="50dp" />
    <Button
        android:text="結束"
        android:layout_marginTop="50dp"
        android:id="@+id/btn_end"
        android:layout_gravity="center"
        android:layout_width="80dp"
        android:layout_height="50dp" />
    <Button
        android:id="@+id/main_bind"
        android:text="繫結"
        android:layout_marginTop="50dp"
        android:layout_gravity="center"
        android:layout_width="80dp"
        android:layout_height="50dp" />
    <Button
        android:id="@+id/main_unbind"
        android:text="解綁"
        android:layout_marginTop="50dp"
        android:layout_gravity="center"
        android:layout_width="80dp"
        android:layout_height="50dp" />
    <Button
        android:id="@+id/main2_btn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="轉到main2"/>
</LinearLayout>

寫一個類繼承service:

package com.example.myapplication15;

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

import static android.content.ContentValues.TAG;

public class MyService extends Service {
    private DownloadBinder mBinder=new DownloadBinder();

    class  DownloadBinder extends Binder {
        public  void startDownload(){
            Log.e(TAG, "MyService: "+"startDownload ");
        }
        public  int getProgress(){
            Log.e(TAG, "MyService: "+"getProgress ");
            return  0;
        }
    }

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.

        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("Myservice", "onCreate: executed" );

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Myservice", "onStartCommand: executed" );
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    Log.e("Service"+ Thread.currentThread().getName(),i+"***" );

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("Myservice"+Thread.currentThread().getName() ,"onDestroy: executed" );
    }
}

當點選開始的時候 log出如圖的效果:
這裡寫圖片描述

當點選結束的時候:
這裡寫圖片描述
當再次連續點選開始時,oncreate 只是被執行了一次。而onStartCommand可以被執行很多次:
這裡寫圖片描述
當點選繫結的時候:
這裡寫圖片描述

當點選解綁的時候 執行銷燬:
這裡寫圖片描述

IntentService的特點及其優缺點?

1是一種服務,比較適合高優先順序的後臺任務
2.任務結束自動退出
3.IntentService是Service的子類,用來處理非同步請求,IntentService在onCreate()通過HandlerThread開啟一個執行緒