Android--從零單排系列(8)--service的使用和利用service進行數據的傳遞

service的簡單介紹就不寫了自己百度這裏只會舉出幾個例子來介紹service的生命週期方法執行順序,已經service的使用場景

詳細請看大神:http://blog.csdn.net/guolin_blog/article/details/11952435

一:service的簡單使用

*1,創建一個myservice繼承service,清單文件註冊service

package service;

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

/**
 * Created by lovelin on 2016/7/5.
 */
public class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();

        Log.e("onCreate", "onCreate被創建了");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("onStartCommand", "onStartCommand被執行了");
        return super.onStartCommand(intent, flags, startId);

    }


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

    @Override
    public void onDestroy() {
        Log.e("onDestroy", "onDestroy被執行了");
        super.onDestroy();
    }
}

*2,activity上有開啓和關閉服務的點擊事件

package com.tzt.activity;

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

import service.MyService;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView stop_service;
    private TextView start_service;

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

    private void initView() {
        start_service = (TextView) findViewById(R.id.start_service);
        stop_service = (TextView) findViewById(R.id.stop_service);
        start_service.setOnClickListener(this);
        stop_service.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_service:
                openService();
                break;
            case R.id.stop_service:
                closeService();
                break;
            default:
                break;
        }
    }

    private void closeService() {
        Intent closeIntent = new Intent(this, MyService.class);
        stopService(closeIntent);
    }

    private void openService() {
        Intent openIntent = new Intent(this, MyService.class);
        startService(openIntent);
    }
}

3,佈局的XML

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

    <TextView
        android:id="@+id/start_service"
        style="@style/TextStye"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="10dp"
        android:text="開啓服務" />

    <TextView
        android:id="@+id/stop_service"
        style="@style/TextStye"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="10dp"
        android:text="停止服務" />


</LinearLayout>

開啓服務的時候:會調用該Service中的onCreate()和onStartCommand()方法,再次點擊開啓服務的時候只會執行onStartCommand()方法,這是由於onCreate()方法只會在Service第一次被創建的時候調用

二:Service和Activity通信

*1,創建代理人類MyBinder 繼承 Binder,並且在service的onBind方法中返回該代理類的對象
*2,具體需要開啓service處理邏輯的代碼在MyBinder類中處理比如我例子中的doSomething(){ }
*3在activity中綁定服務,創建ServiceConnection()對象,通過參數拿到代理人對象
*4,建立綁定關係 (需要注意的是:bindService()方法接收三個參數,第一個參數就是剛剛構建出的Intent對象,第二個參數是前面創建出的ServiceConnection的實例,第三個參數是一個標誌位,這裏傳入BIND_AUTO_CREATE表示在Activity和Service建立關聯後自動創建Service,這會使得MyService中的onCreate()方法得到執行,但onStartCommand()方法不會執行)

注意:

1,任何一個Service在整個應用程序範圍內都是通用的,即MyService不僅可以和MainActivity建立關聯,還可以和任何一個Activity建立關聯,而且在建立關聯時它們都可以獲取到相同的MyBinder實例。

2,一個Service必須要在既沒有和任何Activity關聯又處理停止狀態的時候纔會被銷燬。(注意看條件哦)

3,Service和Thread並沒有一丁點關係,Seriece運行在主線程,Thread運行中子線程,也就是說Serviece進行耗時操作也會ANR,所以想使用Serviece的時候記得在服務站開啓子線程去操作

4,Service的優點,相對應Thread,Activity的銷燬,該activity創建的Thread也會被銷燬,這樣就無法獲取到之前創建的Thread的實例對象,這個是其一,其二是其他的activity無法對其他的activity的Thread實例進行操作,但是Service就不一樣,任何activity多可以和service建立關聯,並且獲取到Service中Binder的代理人對象,即使activity銷燬了,再次創建activity和service的鏈接就可以解決問題,所以service處理後臺的任務activity可以放心的finish();

5,一般標準的服務這麼寫

    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                // 開始執行後臺任務  
            }  
        }).start();  
        return super.onStartCommand(intent, flags, startId);  
    }  

    class MyBinder extends Binder {  

        public void startDownload() {  
            new Thread(new Runnable() {  
                @Override  
                public void run() {  
                    // 執行具體的下載任務  
                }  
            }).start();  
        }  

    }  

具體的看代碼
1,Myservice類

package com.tzt.activity;

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

import service.MyService;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView stop_service;
    private TextView start_service;
    private View bind_service;
    private View unbind_service;

    private MyService.MyBinder myBinder;

    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //拿到servie對象並且向下強轉爲MyBinder
            myBinder = (MyService.MyBinder) service;
            myBinder.doSomething();
        }
    };

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


    private void initView() {
        start_service = (TextView) findViewById(R.id.start_service);
        stop_service = (TextView) findViewById(R.id.stop_service);
        bind_service = findViewById(R.id.bind_service);
        unbind_service = findViewById(R.id.unbind_service);
        start_service.setOnClickListener(this);
        stop_service.setOnClickListener(this);

        bind_service.setOnClickListener(this);
        unbind_service.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_service:
                openService();
                break;
            case R.id.stop_service:
                closeService();
                break;
            case R.id.bind_service:
                mBindService();
                break;
            case R.id.unbind_service:
                munBindService();
                break;
            default:
                break;
        }
    }


    //解綁
    private void munBindService() {
        unbindService(connection);
    }

    //綁定
    private void mBindService() {
        Intent bindIntent = new Intent(this, MyService.class);
        bindService(bindIntent, connection, BIND_AUTO_CREATE);
    }

    //關閉
    private void closeService() {
        Intent closeIntent = new Intent(this, MyService.class);
        stopService(closeIntent);
    }

    //開啓
    private void openService() {
        Intent openIntent = new Intent(this, MyService.class);
        startService(openIntent);
    }
}

*2,activity的操作

package com.tzt.activity;

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

import service.MyService;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView stop_service;
    private TextView start_service;
    private View bind_service;
    private View unbind_service;

    private MyService.MyBinder myBinder;

    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //拿到servie對象並且向下強轉爲MyBinder
            myBinder = (MyService.MyBinder) service;
            myBinder.doSomething();
        }
    };

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


    private void initView() {
        start_service = (TextView) findViewById(R.id.start_service);
        stop_service = (TextView) findViewById(R.id.stop_service);
        bind_service = findViewById(R.id.bind_service);
        unbind_service = findViewById(R.id.unbind_service);
        start_service.setOnClickListener(this);
        stop_service.setOnClickListener(this);

        bind_service.setOnClickListener(this);
        unbind_service.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_service:
                openService();
                break;
            case R.id.stop_service:
                closeService();
                break;
            case R.id.bind_service:   //綁定服務
                mBindService();
                break;
            case R.id.unbind_service:
                munBindService();
                break;
            default:
                break;
        }
    }


    //解綁
    private void munBindService() {
        unbindService(connection);
    }

    //綁定
    private void mBindService() {
        Intent bindIntent = new Intent(this, MyService.class);
        bindService(bindIntent, connection, BIND_AUTO_CREATE);
    }

    //關閉
    private void closeService() {
        Intent closeIntent = new Intent(this, MyService.class);
        stopService(closeIntent);
    }

    //開啓
    private void openService() {
        Intent openIntent = new Intent(this, MyService.class);
        startService(openIntent);
    }
}

三:創建前臺Service

Service的優先級相對來說比較低,當內存不足的時候回有限回收service,所以如果想讓當前的service不被回收的話,可以考慮前臺service,前臺Service和普通Service最大的區別就在於,它會一直有一個正在運行的圖標在系統的狀態欄顯示,下拉狀態欄後可以看到更加詳細的信息,非常類似於通知的效果。當然有時候你也可能不僅僅是爲了防止Service被回收才使用前臺Service,有些項目由於特殊的需求會要求必須使用前臺Service,比如說墨跡天氣,它的Service在後臺更新天氣數據的同時,還會在系統狀態欄一直顯示當前天氣的信息

    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,  
                    "有通知到來", System.currentTimeMillis());  
            Intent notificationIntent = new Intent(this, MainActivity.class);  
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,  
                    notificationIntent, 0);  
            notification.setLatestEventInfo(this, "這是通知的標題", "這是通知的內容",  
                    pendingIntent);  
            startForeground(1, notification);  
            Log.d(TAG, "onCreate() executed");  
        }  

        .........  

    }  

這裏只是修改了MyService中onCreate()方法的代碼。可以看到,我們首先創建了一個Notification對象,然後調用了它的setLatestEventInfo()方法來爲通知初始化佈局和數據,並在這裏設置了點擊通知後就打開MainActivity。然後調用startForeground()方法就可以讓MyService變成一個前臺Service,並會將通知的圖片顯示出來。

現在重新運行一下程序,並點擊Start Service或Bind Service按鈕,MyService就會以前臺Service的模式啓動了,並且在系統狀態欄會彈出一個通欄圖標,下拉狀態欄後可以看到通知的詳細內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章