1. 程式人生 > >Android Service總結

Android Service總結

而後 com btn round pan 但是 rup 進行 end

android裏面的Service是四大組件之一,也是項目中必然需要使用的內容。Service分為綁定服務和非綁定服務,綁定服務是與Activity進行綁定,如果Activity結束綁定的Service也結束,非綁定服務理論上除非調用stopService停止服務則服務不會停止。

使用服務時必須在AndroidManifest先進行配置

        <service android:name=".BackGroupService">

        </service>

        <service android:name=".LocalService">

        </service>

        <service android:name=".ForegroundService">

        </service>

        <service android:name=".MyIntentService">

        </service>

 然後再打開服務

Intent intent = new Intent(context,BackGroupService.class);
startService(intent)

首先是非綁定的服務

package com.kkrs.serivce;

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

/**
 * Created by zd on 2018/12/17.
 */

// 非綁定的service
public class BackGroupService extends Service {
    private boolean flag = true;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("Service","onCreate");
        flag = true;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Service","onStartCommand");
        //在這裏開線程來使用耗時操作
        new Thread(){
            @Override
            public void run() {
                super.run();
                while (flag) {
                    try {
                        sleep(2000);
                        Log.e("Service", "doSomeThing");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        return super.onStartCommand(intent, flags, startId);
    }



    @Override
    public void onDestroy() {
        super.onDestroy();
        flag = false;
        Log.e("Service","onDestroy");

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("Service","onBind");
        return null;
    }
}

 打開服務生命周期為 onCreate -> onStartCommand

 如果服務本身是打開的則直接進入 onStartCommand

關閉服務的生命周期則是進入 onDestory

然後是綁定的服務

綁定服務需要使用ServiceConnection對服務進行連接,在activity中綁定的部分代碼:

 /**
     * ServiceConnection代表與服務的連接,它只有兩個方法,
     * onServiceConnected和onServiceDisconnected,
     * 前者是在操作者在連接一個服務成功時被調用,而後者是在服務崩潰或被殺死導致的連接中斷時被調用
     */
    private ServiceConnection conn;
    private LocalService mService;
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        setContentView(R.layout.activity_main);


        btnBind = (Button)findViewById(R.id.btnBind);
        btnUnBind = (Button)findViewById(R.id.btnUnBind);
        btnGetDatas = (Button)findViewById(R.id.btnGetDatas);
      
        conn = new ServiceConnection() {
            /**
             * 與服務器端交互的接口方法 綁定服務的時候被回調,在這個方法獲取綁定Service傳遞過來的IBinder對象,
             * 通過這個IBinder對象,實現宿主和Service的交互。
             */
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.e("MainActivity", "綁定成功調用:onServiceConnected");
                // 獲取Binder
                LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
                mService = binder.getService();
            }
            /**
             * 當取消綁定的時候被回調。但正常情況下是不被調用的,它的調用時機是當Service服務被意外銷毀時,
             * 例如內存的資源不足時這個方法才被自動調用。
             */
            @Override
            public void onServiceDisconnected(ComponentName name) {
                mService=null;
            }
        };

        final Intent intent = new Intent(this, LocalService.class);

        btnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.e("MainActivity", "綁定調用:bindService");

                bindService(intent, conn, Service.BIND_AUTO_CREATE);

            }
        });

        btnUnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 解除綁定
                Log.e("MainActivity", "解除綁定:bindService");

                if(mService!=null) {
                    Log.e("MainActivity", "mService!=null");
                    mService = null;
                    unbindService(conn);
                }
            }
        });

        btnGetDatas.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mService != null) {
                    // 通過綁定服務傳遞的Binder對象,獲取Service暴露出來的數據
                    Log.e("MainActivity", "從服務端獲取數據:" + mService.getCount());
                } else {

                    Log.e("MainActivity", "還沒綁定呢,先綁定,無法從服務端獲取數據");
                }
            }
        });
    }

 對於綁定服務的代碼

//綁定的service
public class LocalService extends Service {

    private final static String TAG = "LocalService";
    private int count;
    private boolean quit;
    private Thread thread;
    private LocalBinder binder = new LocalBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "Service is invoke Created");
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 每間隔一秒count加1 ,直到quit為true。
                while (!quit) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        });
        thread.start();
    }

    public class LocalBinder extends Binder {
        // 聲明一個方法,getService。(提供給客戶端調用)
        LocalService getService() {
            // 返回當前對象LocalService,這樣我們就可在客戶端端調用Service的公共方法了
            return LocalService.this;
        }
    }

    /**
     * 公共方法
     * @return
     */
    public int getCount(){
        return count;
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "Service is onDestroy");

        this.quit = true;
        super.onDestroy();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "Service is onUnbind");
        return super.onUnbind(intent);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "Service is onBind");

        return binder;
    }
}

 綁定 Created->onBind

綁定時獲得數據 onServiceConnected

解除綁定 onUnbind -> onDestroy

一般來講在服務中使用耗時操作都會新創建一個線程,在線程中來處理,但是在線程的創建和判斷則需要一些邏輯來判斷。但是Android提供了一個專門用了執行耗時操作的Service,IntentService,使用這個就不需要在對你創建的線程進行處理,在這裏將服務裏面創建一個通知來顯示服務的運行情況。

//耗時服務
public class MyIntentService extends IntentService {

    private boolean flag = true;
    private int num = 0;

    //需要一個空構造函數
    public MyIntentService() {
        super("MyIntentService"); // 調用父類的有參構造函數
    }

    public MyIntentService(String name) {
        super(name);
        Log.e("MyIntentService","MyIntentService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("MyIntentService","onCreate");
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        super.onStart(intent, startId);
        flag = true;
        Log.e("MyIntentService","onStart");
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        Log.e("MyIntentService","onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e("MyIntentService","onDestroy");
        super.onDestroy();
        flag = false;
    }

    //這裏進行耗時操作
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.e("MyIntentService","onHandleIntent");
        final Context context = this.getApplicationContext();

        while (flag){
            try {
                sleep(2000);
                Log.e("MyIntentService","start Intent");
                if (num > 100){
                    num = 0;
                }
                Notification notification = new Notification.Builder(context)
                        .setContentTitle("前臺服務的標題")
                        .setContentText("這是一個前臺服務 "+num)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setWhen(System.currentTimeMillis())
                        .build();
                startForeground(110, notification);// 開始前臺服務
                num = num + 1;
            }catch (Exception e){

            }
        }
    }
}

 打開服務生命周期為 onCreate -> onStartCommand->onStart->onHandleIntent

 如果服務本身是打開的則直接進入 onStartCommand->onStart

關閉服務的生命周期則是進入 onDestory

  

Android Service總結