第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Android 入門教程

菜單類控件
菜單:Menu
并發(fā)編程
多線程

服務(wù):Service

今天來學(xué)習(xí) Android 的另一個組件——Service,相比于 Activity,Service通常運(yùn)行在后臺,沒有任何 UI 界面,對用戶是透明感知。通常用來執(zhí)行一些后臺任務(wù),比如播放音樂、下載、加載一些數(shù)據(jù)等等,也可以用作一些進(jìn)程間通信(IPC)機(jī)制。

1. Service 的基本定義

我們還是先來看看官方文檔的部分解釋:

A Service is an application component representing either an application’s desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding declaration in its package’s AndroidManifest.xml. Services can be started with Context.startService() and Context.bindService().

還是用我蹩腳的英語給大家簡單翻譯一下:

Service 是 Android 四大組件之一,通常用來執(zhí)行一些需要長時間運(yùn)行并且不需要和用戶發(fā)送交互的任務(wù),或者是要持續(xù)給其他 App 提供服務(wù)的場景。每一個服務(wù)和 Activity 一樣,需要在包下的 “AndroidManifest.xml”文件中添加注冊,Service可以通過Context.startService()或者Context.bindService()兩種方式啟動。

簡而言之,Service適用于無 UI 界面并且長時間運(yùn)行或者專門給其他 App 提供服務(wù)的場景。

2. Service 的基本概念

為了更好的理解 Service的運(yùn)行機(jī)制,這里提出幾個容易混淆的概念:

  • **進(jìn)程:**進(jìn)程是操作系統(tǒng)為一個 App 提供的獨(dú)立的運(yùn)行單元,是計算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位。
  • **線程:**線程是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實際運(yùn)作單位。一條線程指的是

一般說來,在 Android 中一個 App 運(yùn)行在一個獨(dú)立進(jìn)程,而每一個進(jìn)程可以有多個線程。從編程的角度來看,多個線程是同時并行運(yùn)行的(是否是真并行依賴操作系統(tǒng)的調(diào)度以及 CPU 的核數(shù))。
我們的 Activity 就是運(yùn)行在主線程(UI線程),而 Service 默認(rèn)也是在主線程,所以如果需要做一些耗時操作仍然需要主動放到子線去運(yùn)行。

3. Service 的啟動方式及生命周期

在第 1 小節(jié)的最后講到過,Service 有兩種啟動方式:Context.startService()Context.bindService(),所以也對應(yīng)著兩類 Service:

  • Started Service
  • Bound Service

2.1 Started Service

顧名思義,Started 類型的 Service 就是通過Context.startService()方法啟動的 Service,此時 Service 會立即在后臺啟動,可以調(diào)用Context.stopService()關(guān)閉。當(dāng)然,在 Service 內(nèi)也可以使用Context.stopService()來關(guān)閉自己。

2.2 Bound Service

Service 進(jìn)入 Bound 狀態(tài)需要在 Activity 中調(diào)用Context.bindService()方法,這樣這兩個組件就綁定到了一起,此后二者可以很方便的相互通信,調(diào)用Context.unbindService()可以解除綁定。

其實以上兩種方式的最大差異就是,第 1 種在 start 之后,兩個組件之間就沒有太大關(guān)系了,而第 2 種是以“bind”形式啟動的,啟動之后兩者仍然是綁定關(guān)系,可以進(jìn)行數(shù)據(jù)的傳遞以及狀態(tài)的監(jiān)聽。
這兩種啟動方式的生命周期如下:

service_lifecycle

相比于 Activity,Service 的生命周期就簡化了很多,主要還是依賴于啟動方式,通常如果是一個相對獨(dú)立的 Service,未來不需要和 Activity 強(qiáng)關(guān)聯(lián),推薦使用第一種;當(dāng)然如果需要在 Activity 里面做一些交互甚至對 Service 做一些管理,那么必須使用 bind 的方式。

4. Service 使用示例

接下通過 Service 實現(xiàn)一個非常常見的功能——音樂播放器?,F(xiàn)在市面的絕大多數(shù)音樂播放器都是在一個 Service 里面實現(xiàn)的,它需要長時間在后臺運(yùn)行,所以天然就適合運(yùn)行在 Service 中。

4.1 播放器控制

這里主要是演示 Service 的用法,所以只對播放器進(jìn)行簡單的控制,大家課后感興趣的可以繼續(xù)補(bǔ)充,將示例做成一個更加完整的播放器。我們在 Service 創(chuàng)建的時候初始化播放器,在 Servce 啟動的時候啟動播放器,銷毀的時候關(guān)閉。首先創(chuàng)建“PlayerService”,代碼如下:

package com.emercy.myapplication;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.widget.Toast;

public class PlayerService extends Service {
    MediaPlayer myPlayer;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "Service Created", Toast.LENGTH_LONG).show();

        myPlayer = MediaPlayer.create(this, R.raw.mc_guitar);
        myPlayer.setLooping(false); // Set looping
    }

    @Override
    public void onStart(Intent intent, int startid) {
        Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
        myPlayer.start();
    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
        myPlayer.stop();
    }
}

代碼很簡單,在 Service 的onCreate()中初始化播放器,設(shè)置音頻地址,將你喜歡的音樂放置在 raw 目錄,或者指定一個網(wǎng)絡(luò) Mp3 的 url 地址均可;然后在onStart()中啟動播放器。

4.2 布局文件編寫

我們希望能夠隨時控制播放器的起播和停止,所以需要兩個 Button 分別進(jìn)行控制:

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

    <Button
        android:id="@+id/buttonStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="74dp"
        android:text="啟動播放器" />

    <Button
        android:id="@+id/buttonStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="停止播放" />
</RelativeLayout>

4.3 主控邏輯編寫

在 MainActivity 里主要要做兩件事:

  1. 通過startService()啟動 PlayerService,播放音樂;
  2. 通過stopService結(jié)束播放

package com.emercy.myapplication;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener {
    Button buttonStart, buttonStop;

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

        buttonStart = findViewById(R.id.buttonStart);
        buttonStop = findViewById(R.id.buttonStop);

        buttonStart.setOnClickListener(this);
        buttonStop.setOnClickListener(this);
    }

    public void onClick(View src) {
        switch (src.getId()) {
            case R.id.buttonStart:
                startService(new Intent(this, PlayerService.class));
                break;
            case R.id.buttonStop:
                stopService(new Intent(this, PlayerService.class));
                break;
        }
    }
}

4.4 清單文件

需要注意的是,Service 是一個組件,凡是添加組件都需要在 AndroidManifest.xml 中注冊(動態(tài)注冊除外),否則無法使用:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.emercy.myapplication">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".PlayerService"
            android:enabled="true"
            android:exported="true" />
    </application>

</manifest>

**注意:**如果你的音頻文件是一個遠(yuǎn)程的 url,還需要增加網(wǎng)絡(luò)權(quán)限:

    <uses-permission android:name="android.permission.INTERNET" />

到此,整個初級的播放器就開發(fā)完成了。大家如果感興趣還可以考慮增加其他的功能,比如快進(jìn)、快退、切歌、增加通知欄、展示歌詞等等。

5. 小結(jié)

本節(jié)介紹了 Android 第二個組件,Service 的主要場景是運(yùn)行一些耗時且在后臺的任務(wù),并且相比 Activity 它更輕量且沒有用戶界面。有兩種啟動方式,通過startService()啟動之后 Service 與啟動它的 Activity 再無任何關(guān)聯(lián),而bindService()方式啟動之后二者還會綁定在一起,可以進(jìn)行相互的調(diào)用和數(shù)據(jù)傳遞。同時由于 Service 無 UI 界面,所以在用完后一定要記得要 stop,回收資源。