1. 程式人生 > 實用技巧 >安卓開發 探究服務

安卓開發 探究服務

前言:

  關於安卓開發的筆記,其實基本都是我復現一行程式碼中的程式碼,並加上我自己的理解並解說的,也就是自己記錄著玩玩的,有問題歡迎評論區指正。

0x01 簡介

服務service是安卓裡面的四大元件之一,它的作用就是可以在應用程式關閉時,還可以繼續執行,比如我們平常電腦或手機聽歌的時候,我們會先開啟

音樂軟體,播放音樂後,切換別的應用,幹活去了對吧,但是我們在切換應用的時候,按道理應用這時候是已經掛在後臺了,但是音樂還是在正常播放的

也就是服務是支援應用程式在後臺正常執行的手段。

0x02 安卓多執行緒程式設計

至於為什麼先寫多執行緒,一個是書上是這順序,還有一個原因就是在於服務的幹事的地方,基本都在子執行緒裡面乾的,而服務並不是自己建立子程序的,

這需要我們在服務內部程式碼中去實現的,管他呢,都得學2333

安卓多執行緒和java的多執行緒差不多的,也都是三種方式

1.繼承Thread類,重寫run方法,然後建立對應的執行緒物件,呼叫start()方法,啟動執行緒

 class OneThread extends Thread{
        public void run()
        {
            Log.d("YenKoc", "重寫");
        }
    }
OneThread one=new OneThread();
one.start();

2.實現Runnable介面,重寫run方法,建立對應的例項,然後再新建一個Thread物件,將上面的例項傳入Thread的構造方法中去,再呼叫start()

 class OneThread implements Runnable{
        public void run()
        {

        }
    }
    OneThread one =new OneThread();
    new Thread(one).start();

3.匿名類建立子執行緒的方式

new Thread(new Runnable(){
        public void run()
        {

        }
    }).start()

這種是是最簡單省事的,也是用的多的

然後在子執行緒中是無法更新UI的,這裡書裡也提供了一個簡單的案例,我就不提出來了,就是新建一個佈局,然後設定一個按鈕,一點就新建子執行緒去改變文字框的內容

由於子執行緒中無法更新ui,也就是會出現程式崩潰的情況,這裡就提出另一種完美解決安卓子程序更新ui的操作,安卓提供了一套訊息處理機制,其實之前在app啟動的原始碼中

也看到了訊息機制looper等,通過發訊號的模式去啟動的,這是題外話,這塊我也好久沒看了,又忘了233

這裡通過例項來看

package com.example.servicetest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.IpSecManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.nio.BufferUnderflowException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private TextView text;
    public static final int UPDATE_TEXT=1;
    private Handler handler=new Handler(){
        public void handleMessage(Message msg){
            switch (msg.what)
            {
                case UPDATE_TEXT:
                    text.setText("Nice to meet you");
                    break;
                default:
                    break;
            }
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button changeText=(Button)findViewById(R.id.change_text);
        changeText.setOnClickListener(this);

    }
    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.change_text:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message message=new Message();
                        message.what=1;
                        handler.sendMessage(message);
                    }
                }).start();
            default:
                
                        
        }


    }
}

新建一個handler物件,並重寫了handlerMessage方法,裡面主要是根據訊息中的what欄位來選擇不同的處理方式,

然後在點選按鈕後,實際上是通過建立子程序,然後在子程序中,傳送了一個訊息給主執行緒handler,然後由主線

程來更新ui,這種非同步訊息處理機制,太酷了233,想當於領導在子執行緒裡面指揮,小弟在主執行緒裡面幹活。

至於原理也挺簡單當,看圖

message:字面意思,作為通訊用的

handler: 用來處理訊息的,要重寫handleMessage方法

MessageQueue:訊息佇列,因為訊息有先後順序的,相當於訊息容器,把訊息都裝到裡面

looper:訊息佇列的管家,一旦執行會輪詢訊息佇列,看看裡面是否有訊息,如果有就傳送,沒有的話就阻塞

之前使用的runOnUiThread其實就是上面那套的封裝,所以很香,所以那裡面是可以對ui操作的

0x02 服務

終於到服務了。。

package com.example.servicetest;

        import android.app.Service;
        import android.content.Intent;
        import android.os.IBinder;

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");
    }
    //服務建立的時候呼叫
    public void onCreate()
    {
        super.onCreate();
    }
    //服務每次啟動時被呼叫
    public int onStartCommand(Intent intent,int flags,int startId)
    {
        return super.onStartCommand(intent,flags,startId);
    }
    public void onDestroy()
    {
        super.onDestroy();
    }

}

新建一個service類,然後重寫onCreate()方法,onStartCommand()方法(主要邏輯是寫到這裡),onDestroy()方法,

2.服務的啟動和停止,元件之間的啟動都是通過intent物件來啟動的

package com.example.servicetest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.IpSecManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.nio.BufferUnderflowException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      Button startService=(Button)findViewById(R.id.start_service);
        Button stopService=(Button)findViewById(R.id.stop_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
    }
    public void onClick(View v)
    {
        switch (v.getId()) {
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntent=new Intent(this,MyService.class);
                stopService(stopIntent);
                break;
        }
    }

}

然後在MyService類改下程式碼

package com.example.servicetest;

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

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");
    }
    //服務建立的時候呼叫
    public void onCreate()
    {
        super.onCreate();
        Log.d("MyService", "onCreate executed");
    }
    //服務每次啟動時被呼叫
    public int onStartCommand(Intent intent,int flags,int startId)
    {
        Log.d("MyService", "onStartCommand: executed");
        return super.onStartCommand(intent,flags,startId);
    }
    public void onDestroy()
    {
        super.onDestroy();
        Log.d("MyService", "onDestroy: executed");
    }

}

3.活動與服務之間的通訊,因為之前這種方式都是活動啟動完服務之後,就不管不顧了,無法知道服務具體邏輯是什麼,也控制不了,所以安卓想讓活動和服務緊密一點,所以提出了Binder機制

未完待續