【Android】Service服務的簡單使用

Service最大的特點就是無界面後臺運行,不像Activity那樣可以與用戶交互。我們可以用Service用於後臺工作,比如說下載、播放音樂等等。當然服務也是要依賴於創建服務的進程才能工作的,而且服務並不會主動開啓線程

一、創建Service

1、創建Service

右鍵New–Service–Service,修改名稱後直接創建。之後可以重新它的一些常用方法

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.e("MyService", "onCreate: 服務已經被創建");
    }
    //服務被啓動時調用,服務只能被創建一次,但是可以被調用多次
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("MyService", "onStartCommand: 服務已經啓動");
        return super.onStartCommand(intent, flags, startId);

    }
    //服務被銷燬時調用
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("MyService", "onDestroy: 服務已經銷燬");
    }
}

也可以手動創建一個Java文件,然後繼承與Service類,再去AndroidManifest添加Service標籤

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ice.androidpractice17_service1">
    <application
        android:allowBackup="true"
        ......
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">
        </service>
        <activity android:name=".MainActivity">
            ......
        </activity>
    </application>
</manifest>

2、layout佈局

就放兩個button好了,一個開啓服務,另一個關閉服務

<?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"
    android:gravity="center"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/btn_startService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="start_Service"/>
    <Button
        android:id="@+id/btn_stopService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="stop_Service"/>

</LinearLayout>

3、Java代碼

主要是開啓和停止服務

public class MainActivity extends AppCompatActivity implements View .OnClickListener{
    private Button btn_startService,btn_stopService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_startService = findViewById(R.id.btn_startService);
        btn_stopService = findViewById(R.id.btn_stopService);
        btn_startService.setOnClickListener(this);
        btn_stopService.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_startService:
                Intent intent_start = new Intent(this,MyService.class);
                startService(intent_start);//開啓服務
                break;
            case R.id.btn_stopService:
                Intent intent_stop = new Intent(this,MyService.class);
                stopService(intent_stop);//停止服務,也可以在Service裏任意位置調用stopSelf()停止服務
                break;
        }
    }
}

二、連接Service與Activity通信

上面的代碼只是開啓和停止服務,但是更多的時候要與Activity進行通信,這時候就需要在Activity與Service建立連接

1、修改佈局

新添加兩個button,分別用於綁定和解綁服務

<?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"
    android:gravity="center"
    tools:context=".MainActivity">
	.......
    <Button
        android:id="@+id/btn_bindService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="bind_Service"/>
    <Button
        android:id="@+id/btn_unbindService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="unbind_Service"/>

</LinearLayout>

2、新建一個內部類

我們在MyService新建一個內部類,用於處理自己的業務邏輯,並且在onBind()方法中將其return給Activity那邊

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

    //新建一個繼承於Binder的內部類,用於實現自己的邏輯代碼
    class PlayMusicBinder extends Binder {
        public void startPlayMusic(){
            Log.e("DownloadBinder", "startDownload: 開始播放音樂");
        }
        public int getProgress(){
            Log.e("DownloadBinder", "getProgress: 當前播放進度是XX%" );
            return 0;
        }

    }

    private PlayMusicBinder mBinder = new PlayMusicBinder();//實例化內部類
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mBinder;//返回新建的內部類,Activity連接服務時會接收
    }
    //服務被創建時調用
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("MyService", "onCreate: 服務已經被創建");
    }
	......

}

3、在Activity中調用

public class MainActivity extends AppCompatActivity implements View .OnClickListener{
    private Button btn_startService,btn_stopService;
    private Button btn_bindService,btn_unbindService;
    //新建一個匿名的ServiceConnection類,重寫連接和斷開服務的兩個方法處理自己的邏輯代碼
    private ServiceConnection connection = new ServiceConnection() {
        //連接服務,接收MyService類返回的mBinder
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.e("ServiceConnection", "onServiceConnected: 服務已連接");
            //新建一個playMusicBinder類去實現自己的邏輯
            MyService.PlayMusicBinder playMusicBinder = (MyService.PlayMusicBinder) iBinder;
            playMusicBinder.startPlayMusic();
            playMusicBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.e("ServiceConnection", "onServiceDisconnected: 服務已斷開" );
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_startService = findViewById(R.id.btn_startService);
        ......
        btn_unbindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            ......
             //綁定服務
            case R.id.btn_bindService:
                Intent bindIntent = new Intent(this,MyService.class);
                bindService(bindIntent,connection,BIND_AUTO_CREATE);
                break;
             //斷開綁定服務
            case R.id.btn_unbindService:
                unbindService(connection);
                break;
             default:
                 break;
        }
    }
    
}

提示:

通過上面的代碼,我們已經可以調用Service的自定義代碼了,但是還需要注意的是:

想要destroy()服務,必須要把stopService()和unbindService()都調用

還需要注意的是,上面的代碼是在主線程執行的,耗時任務,應該開啓子線程

如果覺得Service太難用,還可以使用IntentService,會自動開啓新線程並且完成任務之後會自動停止服務

【Android】IntentService的使用

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