溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

android基礎(chǔ)知識(shí)之服務(wù)

發(fā)布時(shí)間:2020-07-21 21:38:25 來源:網(wǎng)絡(luò) 閱讀:189 作者:石榴裙下者 欄目:移動(dòng)開發(fā)

##01_start開啟服務(wù)的生命周期(重點(diǎn))

服務(wù)的特點(diǎn):
 
        服務(wù)被創(chuàng)建時(shí)調(diào)用onCreate、onStartCommand;
           服務(wù)只能被創(chuàng)建一次,可以開啟多次onStartCommand;
           服務(wù)只能被停止一次onDestroy; 
        沒有onPause、onStop、onResume、onRestart方法,因?yàn)閟ervice沒有界面,長(zhǎng)期運(yùn)行在后臺(tái)。

生命周期的方法:
 
        onCreate:服務(wù)被創(chuàng)建的時(shí)候調(diào)用這個(gè)方法;
        onStartCommand :開啟服務(wù);
        onDestroy:銷毀服務(wù);

##02_bind方式開啟服務(wù)的生命周期(重點(diǎn))

    bindService、unbindService的特點(diǎn):

    1、第一次綁定服務(wù)時(shí),先創(chuàng)建服務(wù)對(duì)象,在綁定,調(diào)用了oncreate onbind;
    2、解除綁定的服務(wù)時(shí),調(diào)用onUnbind、onDestroy;
    3、服務(wù)只能被幫頂一次;
    4、服務(wù)只能被解除一次,多次解除程序會(huì)拋出異常;
    5、使用bindservice方式開啟的服務(wù),會(huì)隨著界面的退出而解除綁定并且銷毀服務(wù)對(duì)象;

    生命周期:

    1、第一次綁定服務(wù)時(shí)創(chuàng)建服務(wù)對(duì)象:onCreate、onbind;
    2、界面關(guān)閉時(shí)銷毀服務(wù)對(duì)象:onUnbind、onDestroy;

    推薦的混合方式:
    1、startService:可以讓服務(wù)長(zhǎng)期運(yùn)行在后臺(tái);
    2、bindService:綁定服務(wù),為了調(diào)用服務(wù)的業(yè)務(wù)邏輯方法;
    3、unbindService:解除綁定,不能在調(diào)用服務(wù)里業(yè)務(wù)邏輯方法;
    4、stopService:停止服務(wù),銷毀服務(wù)對(duì)象;

##03_為什么要引入bindservice的API

    目的:為了調(diào)用服務(wù)中業(yè)務(wù)邏輯方法:

##04_綁定服務(wù)調(diào)用服務(wù)方法的過程

    通過中間人調(diào)用服務(wù)里面的業(yè)務(wù)邏輯方法:

    1、在服務(wù)中添加一個(gè)中間人的類,這個(gè)類繼承了Binder,Binder實(shí)現(xiàn)了IBinder接口,所以中間人就是一個(gè)IBinder的實(shí)現(xiàn)類;
    2、在綁定服務(wù)時(shí)調(diào)用的onBind方法返回中間人對(duì)象;
    3、在activity中綁定服務(wù)成功時(shí)獲取中間人對(duì)象;
    4、在activity中調(diào)用中間人的方法(這個(gè)方法中調(diào)用服務(wù)的業(yè)務(wù)邏輯方法);

代碼:

MainActivity.java:

    package com.itheima.bindservice;

    import com.itheima.bindservice.TestService.MyBinder;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.view.View;
    
    public class MainActivity extends Activity {

    private MyConn conn;
    private Intent intent;

    //中間人對(duì)象
    private MyBinder myBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void call(View view) {
        myBinder.callMethodInService();
    }

    public void start(View view) {
        intent = new Intent(this, TestService.class);
        startService(intent);
    }

    public void stop(View view) {
        stopService(intent);
    }

    public void bind(View view) {
    
        conn = new MyConn();
        // 綁定服務(wù)
        // intent開啟服務(wù)的意圖對(duì)象
        // MyConn在activity與service之間創(chuàng)建的一個(gè)連接,作為通訊的渠道
        // BIND_AUTO_CREATE 綁定服務(wù)時(shí)如果服務(wù)不存在,就會(huì)縣創(chuàng)建一個(gè)服務(wù)對(duì)象,然后在綁定
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    public void unbind(View view) {
        //解除綁定
        unbindService(conn);
    }

    private class MyConn implements ServiceConnection {

        /**
         * 服務(wù)綁定成功后調(diào)用這個(gè)方法
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            myBinder = (MyBinder) service;
        }

        /**
         * 解除服務(wù)成功時(shí)調(diào)用這個(gè)方法
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
        }
    }
    }

TestService.java:

    package com.itheima.bindservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    
    public class TestService extends Service {

    /*
     * 綁定服務(wù)的時(shí)候會(huì)調(diào)用這個(gè)方法
     * return : 綁定服務(wù)成功后返回一個(gè)IBinder類型的數(shù)據(jù)對(duì)象
     */
    @Override
    public IBinder onBind(Intent arg0) {
        System.out.println("--------onBind---------");
        return new MyBinder();
    }
    
    /**
     * 解除綁定的服務(wù)時(shí)調(diào)用這個(gè)方法
     */
    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("--------onUnbind---------");
        return super.onUnbind(intent);
    }
    
    
    @Override
    public void onCreate() {
        System.out.println("--------onCreate---------");
        super.onCreate();
    }
    
    @Override
    public void onDestroy() {
        System.out.println("--------onDestroy---------");
        super.onDestroy();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("--------onStartCommand---------");
        return super.onStartCommand(intent, flags, startId);
    }
    
    /**
     * 業(yè)務(wù)邏輯方法
     */
    public void methodInService(){
        System.out.println("========methodInService========");
    }

    /**
     * 中間人,
     * @author Administrator
     *
     */
    public class MyBinder extends Binder{
        
        public void callMethodInService(){
            //調(diào)用業(yè)務(wù)邏輯方法
            methodInService();
        }
    }
    }

##05_綁定服務(wù)抽取接口(重點(diǎn))

    接口的作用:對(duì)外暴露功能,隱藏實(shí)現(xiàn)的細(xì)節(jié);

    步驟:
    1、創(chuàng)建一個(gè)接口,里面寫一個(gè)方法(對(duì)外暴露的方法):
    2、在服務(wù)類里面,讓中間人實(shí)現(xiàn)這個(gè)接口,并且實(shí)現(xiàn)接口中方法,在實(shí)現(xiàn)的方法中調(diào)用服務(wù)的業(yè)務(wù)邏輯方法;
    3、在activity中綁定服務(wù)成功時(shí),得到接口類型的中間人對(duì)象;
    4、在activity中調(diào)用中間人的方法;

代碼:

MainActivity.java:

    package com.itheima.bindservice;
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.view.View;

    public class MainActivity extends Activity {

    private MyConn conn;
    private Intent intent;
    //中間人對(duì)象
    private IService myBinder;

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

    
    public void call(View view) {
        myBinder.callMethodInService();
    }

    public void start(View view) {
        intent = new Intent(this, TestService.class);
        startService(intent);
    }

    public void stop(View view) {
        stopService(intent);
    }

    public void bind(View view) {
        conn = new MyConn();
        // 綁定服務(wù)
        // intent開啟服務(wù)的意圖對(duì)象
        // MyConn在activity與service之間創(chuàng)建的一個(gè)連接,作為通訊的渠道
        // BIND_AUTO_CREATE 綁定服務(wù)時(shí)如果服務(wù)不存在,就會(huì)縣創(chuàng)建一個(gè)服務(wù)對(duì)象,然后在綁定
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    public void unbind(View view) {
        //解除綁定
        unbindService(conn);
    }

    private class MyConn implements ServiceConnection {

        /**
         * 服務(wù)綁定成功后調(diào)用這個(gè)方法
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder = (IService) service;
        }

        /**
         * 解除服務(wù)成功時(shí)調(diào)用這個(gè)方法
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
        }
    }
    }


TestService.java:

    package com.itheima.bindservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    
    public class TestService extends Service {

    /*
     * 綁定服務(wù)的時(shí)候會(huì)調(diào)用這個(gè)方法
     * return : 綁定服務(wù)成功后返回一個(gè)IBinder類型的數(shù)據(jù)對(duì)象
     */
    @Override
    public IBinder onBind(Intent arg0) {
        System.out.println("--------onBind---------");
        return new MyBinder();
    }
    
    /**
     * 解除綁定的服務(wù)時(shí)調(diào)用這個(gè)方法
     */
    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("--------onUnbind---------");
        return super.onUnbind(intent);
    }
    
    
    @Override
    public void onCreate() {
        System.out.println("--------onCreate---------");
        super.onCreate();
    }
    
    @Override
    public void onDestroy() {
        System.out.println("--------onDestroy---------");
        super.onDestroy();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("--------onStartCommand---------");
        return super.onStartCommand(intent, flags, startId);
    }
    
    /**
     * 業(yè)務(wù)邏輯方法
     */
    public void methodInService(){
        System.out.println("========methodInService========");
    }

    /**
     * 中間人,
     * @author Administrator
     *
     */
    private class MyBinder extends Binder implements IService{
        
        //實(shí)現(xiàn)接口中方法
        public void callMethodInService(){
            //調(diào)用業(yè)務(wù)邏輯方法
            methodInService();
        }
        
        public void eat(){
            System.out.println("=======eat======");
        }
        
        public void sn(){
            System.out.println("=======sn======");
        }
        
        public void ktv(){
            System.out.println("=======ktv======");
        }
        }
    }

##06_服務(wù)的應(yīng)用場(chǎng)景

    應(yīng)用場(chǎng)景:需要在后臺(tái)運(yùn)行一個(gè)程序,需要與服務(wù)器端通訊數(shù)據(jù);
    常見的服務(wù)應(yīng)用場(chǎng)景:天氣預(yù)報(bào)、股票軟件;

##07_利用服務(wù)注冊(cè)廣播接收者

     使用代碼注冊(cè)廣播接收者原因:操作比較頻繁的事件,在激活廣播接收者時(shí),需要去讀取清單文件,解析xml格式的數(shù)據(jù),這個(gè)過程占用的資源比較大,耗時(shí)較長(zhǎng)。

     使用代碼注冊(cè)的廣播接收者,啟動(dòng)的時(shí)候比較快。

工程代碼:

配置文件:
    
        <receiver android:name="com.itheima.coderegistreceiver.ScreenBroadcastreceiver">
        </receiver>
        
        <service android:name="com.itheima.coderegistreceiver.ScreenReceiverService"></service>

代碼:

        public class MainActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            Intent intent = new Intent(this,ScreenReceiverService.class);
            startService(intent);
        }
        }


    ScreenReceiverService.java:


            package com.itheima.coderegistreceiver;
            
            import android.app.Service;
            import android.content.Intent;
            import android.content.IntentFilter;
            import android.os.IBinder;
            
            public class ScreenReceiverService extends Service {
        
            @Override
            public IBinder onBind(Intent intent) {
                // TODO Auto-generated method stub
                return null;
            }
        
            @Override
            public void onCreate() {
                super.onCreate();
                // 1、創(chuàng)建一個(gè)廣播接收者的對(duì)象
                ScreenBroadcastreceiver receiver = new ScreenBroadcastreceiver();
                // 2、為廣播接收者創(chuàng)建意圖過濾器
                IntentFilter filter = new IntentFilter();
                // 3、在意圖過濾器中設(shè)置廣播接收者需要接收的事件類型
                filter.addAction("android.intent.action.SCREEN_ON");
                filter.addAction("android.intent.action.SCREEN_OFF");
                // 4、注冊(cè)廣播接收者
                this.registerReceiver(receiver, filter);
            }
        }


##08_遠(yuǎn)程服務(wù)aidl的寫法(重點(diǎn))
    遠(yuǎn)程服務(wù):在同一個(gè)設(shè)備上安裝的其他應(yīng)用程序,包含一個(gè)服務(wù)的應(yīng)用程序。
    本地服務(wù):在自己的應(yīng)用程序中寫另一個(gè)服務(wù)的類;


    aidl: Android Interface Definition language 安卓的接口定義語(yǔ)言;
    這個(gè)格式的文件,就是對(duì)外共享的接口的文件,可以把這個(gè)文件拷貝任何工程里,可以調(diào)用遠(yuǎn)程服務(wù)的接口;

    IPC: Inter Process Communication 進(jìn)程間的通訊;



在本地應(yīng)用程序中調(diào)用遠(yuǎn)程的服務(wù)接口:

 步驟:
    1、寫遠(yuǎn)程的工程,寫一個(gè)服務(wù);
    (1)創(chuàng)建一個(gè)服務(wù)類,重寫了onBind方法;
    (2)在服務(wù)類里寫了一個(gè)中間人,繼承了Binder;
    (3)寫一個(gè)接口類,對(duì)外暴露了一個(gè)方法;
    (4)在服務(wù)類里讓中間人實(shí)現(xiàn)了這個(gè)接口,重寫接口的方法(在這個(gè)方法里面調(diào)用服務(wù)的業(yè)務(wù)邏輯方法);
    (5)修改IService類的格式,改成aidl格式(讓它作為一個(gè)對(duì)外開放的共享接口文件);
    (6)讓中間人繼承Stub;
    2、創(chuàng)建一個(gè)本地應(yīng)用程序,調(diào)用遠(yuǎn)程的服務(wù)接口:
    (1)創(chuàng)建一個(gè)與遠(yuǎn)程服務(wù)相同的包名,然后把a(bǔ)idl文件拷貝到這個(gè)包里;
    (2)在activity中綁定服務(wù)成功時(shí)得到IService類型的中間人;
    (3)在activity中調(diào)用中間人的方法;


遠(yuǎn)程服務(wù):

    package com.itheima.remoteservice;

    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    
    import com.itheima.remoteservice.IService.Stub;
    
    public class RemoteService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("=========onBind============");
        return new MyBinder();
    }
    
    public void methodInService(){
        System.out.println("================methodInService===========");
    }
    
    
    
    //中間人 繼承 Stub,能夠是進(jìn)程間的通訊
    private class MyBinder extends Stub{

        @Override
        public void callMethodInService() {
            //調(diào)用服務(wù)的業(yè)務(wù)邏輯方法
            methodInService();
        }
        
    }

}


本地應(yīng)用程序:


    package com.itheima.localapp;

    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.view.View;
    
    import com.itheima.remoteservice.IService;
    import com.itheima.remoteservice.IService.Stub;
    
    public class MainActivity extends Activity {

    private IService myBinder;

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

    public void bind(View view ){
        Intent intent = new Intent();
        intent.setAction("com.itheima.remoteservice.REMOTESERVICE");
        
        //綁定服務(wù)
        bindService(intent, new MyConn(), BIND_AUTO_CREATE);
    }
    
    
    public void call(View view ){
        try {
            //調(diào)用遠(yuǎn)程服務(wù)接口的方法
            myBinder.callMethodInService();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    
    private class MyConn implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //把中間人作為接口來使用
            myBinder = Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
        
    }

    }
   

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI