10探究服務(wù)-服務(wù)的用法

定義一個(gè)服務(wù)

  1. 新建一個(gè)項(xiàng)目,右擊com.example.servicetest --> New --> Service -->Service,會(huì)彈出一個(gè)窗口,如下所示:


    創(chuàng)建服務(wù)的窗口.png
  • 可以看到這個(gè)服務(wù)的名字為MyService唧瘾,Exported表示是否允許除了當(dāng)前程序之外的其他程序訪問這個(gè)服務(wù),Enabled屬性表示是否啟用這個(gè)服務(wù),建立完成后可以看到
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");
    }
}
  • 自定義的MyService是繼承子Service岸裙,這里面只有一個(gè)onBind()方法,這個(gè)方法是Service中唯一一個(gè)抽象的方法速缆,所以在子類中必須實(shí)現(xiàn)降允,以后會(huì)用到的
  1. 這個(gè)時(shí)候Service中還是空空如也,所以就得重寫Service中的另外一些方法了艺糜,如下所示:
public class MyService extends Service {
    public MyService() {
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

}

  • 可以看到這里重寫了3個(gè)方法剧董,
    • onCreate()在服務(wù)創(chuàng)建的時(shí)候調(diào)用,
    • onStartCommand()會(huì)在每次服務(wù)啟動(dòng)的時(shí)候調(diào)用破停,
    • onDestroy()會(huì)在服務(wù)銷毀的時(shí)候調(diào)用
  • 通常情況下翅楼,如果希望服務(wù)一旦啟動(dòng)就立刻去執(zhí)行某個(gè)動(dòng)作,就可以將邏輯寫在onStartCommand()方法中真慢,當(dāng)服務(wù)銷毀的時(shí)候毅臊,就可以在onDestroy()方法中回收那些不用的資源
  1. 要注意的是每一個(gè)服務(wù)要在AndroidManifest.xml文件中進(jìn)行注冊(cè),但是android Studio已經(jīng)幫我們注冊(cè)好了
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.md.server">

    <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">
      ...
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">  
        </service>
    </application>
</manifest>

  • 一個(gè)服務(wù)就這樣定義好了

啟動(dòng)和停止服務(wù)

啟動(dòng)和停止一個(gè)服務(wù)還要借助Intent來實(shí)現(xiàn)黑界,在項(xiàng)目中實(shí)戰(zhàn)一下

  1. 修改activity_main.xml中的代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>
    
    <Button
        android:id="@+id/start_Service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start_service"/>

    <Button
        android:id="@+id/stop_Service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="stop_service"/>
</LinearLayout>

  • 添加兩個(gè)按鈕管嬉,一個(gè)用來啟動(dòng)服務(wù),一個(gè)用來停止服務(wù)
  1. 修改MainActivity中的代碼
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button start_Service = (Button)findViewById(R.id.start_Service);
        Button stop_Service = (Button)findViewById(R.id.stop_Service);
        start_Service.setOnClickListener(this);
        stop_Service.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.start_Service:
                Intent startIntent = new Intent(this,MyService.class);
                // 啟動(dòng)服務(wù)
                startService(startIntent);
                break;
            case R.id.stop_Service:
                Intent stopIntent = new Intent(this,MyService.class);
                // 停止服務(wù)
                stopService(stopIntent);
                break;
            default:
                break;
        }
    }
}
  • 首先獲取到了兩個(gè)按鈕的實(shí)例园爷,并且綁定了點(diǎn)擊事件

  • 在點(diǎn)擊事件中宠蚂,首先構(gòu)建了一個(gè)Intent對(duì)象,里面?zhèn)魅胱远x的服務(wù)童社,并調(diào)用這個(gè)startService()來啟動(dòng)服務(wù)求厕,和調(diào)用stopService()方法停止停止這個(gè)服務(wù)

  • startService()和stopService()方法都是定義在COntext類中的,所以就可以直接調(diào)用這兩個(gè)方法

  • 注意扰楼,這里完全是由活動(dòng)來決定服務(wù)何時(shí)停止的呀癣,如果沒有點(diǎn)擊這個(gè)stop_service按鈕,服務(wù)就會(huì)一直處于運(yùn)行狀態(tài)弦赖,這個(gè)時(shí)候怎么讓服務(wù)停止呢项栏,只要在MyService的任何一個(gè)位置調(diào)用stopSelf()方法就可以讓這個(gè)服務(wù)停止了

  1. 怎么才能證實(shí)服務(wù)啟動(dòng)了呢,這個(gè)時(shí)候只要在MyService的方法中添加打印日志就可以了蹬竖,如下
public class MyService extends Service {
    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","onCreate executed");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService","onStartCommand executed");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        
        super.onDestroy();
        Log.d("MyService","onDestroy executed");
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
  • 運(yùn)行程序沼沈,


    主頁面.png
  • 點(diǎn)擊Start Service按鈕就可以看到打印日志


    啟動(dòng)服務(wù)打印的日志.png
  • 點(diǎn)擊設(shè)置-->開發(fā)者選項(xiàng)--> 正在運(yùn)行的服務(wù) 就可以看到了


    正在運(yùn)行的服務(wù).png
  • 然后點(diǎn)擊Stop Servire按鈕流酬,看打印日志


    停止服務(wù).png

    此時(shí)這個(gè)服務(wù)就停止了

  • 這里要注意的是onCreate()和onStartCommand()方法,onCreate()是在服務(wù)第一次創(chuàng)建的時(shí)候調(diào)用的列另,而onStartCommand()則在每次啟動(dòng)服務(wù)的時(shí)候就會(huì)調(diào)用的芽腾,第一次執(zhí)行兩個(gè)方法都會(huì)執(zhí)行,之后再點(diǎn)擊start Service按鈕页衙,只有onStartCommand()方法會(huì)得到執(zhí)行

服務(wù)和活動(dòng)進(jìn)行通信

雖然服務(wù)是在活動(dòng)里的摊滔,但是啟動(dòng)服務(wù)后,活動(dòng)于服務(wù)基本就沒有什么關(guān)系了店乐,因?yàn)榉?wù)里的方法得到執(zhí)行艰躺,之后服務(wù)就會(huì)一直處于運(yùn)行的狀態(tài),但是具體運(yùn)行邏輯的時(shí)候眨八,活動(dòng)控制不了服務(wù)了腺兴,有沒有辦法讓活動(dòng)這服務(wù)關(guān)聯(lián)起來?就是在活動(dòng)中指揮服務(wù),讓服務(wù)干什么踪古,服務(wù)就干什么含长,這個(gè)時(shí)候就得借助onBind()方法了

  1. 比如希望在MyService里提供一個(gè)下載功能,在活動(dòng)中可以決定何時(shí)開始下載伏穆,以及隨時(shí)查看下載進(jìn)度拘泞,實(shí)現(xiàn)這個(gè)功能的思路就是創(chuàng)建一個(gè)專門的Binder對(duì)象來對(duì)下載功能進(jìn)行管理,修改MyService中的代碼

public class MyService extends Service {

    private DownloadBinder mBinder = new DownloadBinder();
    
    class DownloadBinder extends Binder{
        public void startDownload(){
            Log.d("MyService","startDownload executed");
        }
        public int getProgress(){
            Log.d("MyService","getProgress executed");
            return 0;
        }
    }
    ...

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}
  • 這個(gè)時(shí)候新建一個(gè)DownloadBinder類繼承自Binder枕扫,然后在它的內(nèi)部提供了開始下載以及查看下載的方法陪腌,當(dāng)然這只是一個(gè)模擬方法,分別打印日志
  • 然后在MyService中創(chuàng)建一個(gè)DownloadBinder的實(shí)例烟瞧,然后在onBind()方法中將這個(gè)實(shí)例返回
  1. 在活動(dòng)中如何調(diào)用服務(wù)里的這些方法诗鸭,首先在布局文件中新增兩個(gè)按鈕,修改activity.xml中的代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>
    ...
    <Button
        android:id="@+id/bind_Service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind_Service"/>

    <Button
        android:id="@+id/unbind_Service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbind_Service"/>
</LinearLayout>
  • 這兩個(gè)按鈕分別用于綁定服務(wù)和取消綁定服務(wù)参滴,
  1. 當(dāng)一個(gè)活動(dòng)和服務(wù)綁定了之后强岸,就可以調(diào)用該服務(wù)中的Bunder提供的方法,修改MainActivity中的代碼
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private MyService.DownloadBinder downloadBinder;
    // 創(chuàng)建一個(gè)匿名類
    private ServiceConnection connection = new ServiceConnection() {
        // 綁定成功調(diào)用
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //通過向下轉(zhuǎn)型得到了DownloadBinder的實(shí)例
            downloadBinder = (MyService.DownloadBinder) iBinder;
            // 調(diào)用方法
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }
        // 解除綁定調(diào)用
        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button start_Service = (Button)findViewById(R.id.start_Service);
        Button stop_Service = (Button)findViewById(R.id.stop_Service);
        start_Service.setOnClickListener(this);
        stop_Service.setOnClickListener(this);
        Button bind_Service = (Button)findViewById(R.id.bind_Service);
        Button unbind_Service = (Button)findViewById(R.id.unbind_Service);
        bind_Service.setOnClickListener(this);
        unbind_Service.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.start_Service:
                Intent startIntent = new Intent(this,MyService.class);
                // 啟動(dòng)服務(wù)
                startService(startIntent);
                break;
            case R.id.stop_Service:
                Intent stopIntent = new Intent(this,MyService.class);
                // 停止服務(wù)
                stopService(stopIntent);
                break;
            case R.id.bind_Service:
                Intent bindIntent = new Intent(this,MyService.class);
                // 綁定服務(wù)砾赔,第二個(gè)參數(shù)是前面創(chuàng)建ServiceConnection的實(shí)例
                bindService(bindIntent,connection,BIND_AUTO_CREATE)
                break;
            case R.id.unbind_Service:
                // 解除綁定
                unbindService(connection);
                break;
            default:
                break;
        }
    }
}

  • 首先創(chuàng)建一個(gè)ServiceConnection匿名類蝌箍,這個(gè)類中重寫onServiceConnected()和onServiceDisconnected()方法,這兩個(gè)方法分別用于活動(dòng)與服務(wù)成功綁定和解除綁定的時(shí)候調(diào)用暴心,
  • 在onServiceConnected()方法中妓盲,通過向下轉(zhuǎn)型得到了 DownloadBinder的實(shí)例,通過這個(gè)實(shí)例专普,就可以調(diào)用 DownloadBinder中的任何方法了
  • 當(dāng)然了悯衬,這只是基礎(chǔ)工作,真正的綁定是在點(diǎn)擊按鈕的時(shí)候檀夹,首先構(gòu)建一個(gè)Intent對(duì)象
  • 然后調(diào)用bindService()方法筋粗,第一個(gè)參數(shù)是Intent對(duì)象策橘,第二個(gè)參數(shù)是前面創(chuàng)建ServiceConnection的實(shí)例,第三個(gè)參數(shù)是一個(gè)標(biāo)志位亏狰,BIND_AUTO_CREATE表示在活動(dòng)和服務(wù)進(jìn)行綁定后自動(dòng)創(chuàng)建活動(dòng)役纹,這個(gè)時(shí)候就會(huì)使得MyService中的onCreate()方法得到執(zhí)行偶摔,但是onStartCommand()方法不會(huì)執(zhí)行
  • 解除綁定只要調(diào)用unbindService()方法就可以暇唾,傳入的參數(shù)也是前面創(chuàng)建ServiceConnection的實(shí)例
  • 運(yùn)行程序,就可以看到


    新的主頁面.png

    點(diǎn)擊這個(gè)Bind Service按鈕,看打印日志


    綁定服務(wù)打印.png

    可以看到辰斋,onCreate()方法先得到執(zhí)行策州,然后調(diào)用的方法也得到了執(zhí)行
  • 注意:任何一個(gè)服務(wù)在整個(gè)應(yīng)用程序范圍內(nèi)都是通用的,即MyService不僅可以和MainActivity綁定宫仗,還可以和任何一個(gè)其他活動(dòng)進(jìn)行綁定够挂,而且在綁定完成后他們都可以獲取到相同的DownloadBinder實(shí)例

活動(dòng)的生命周期

  1. 一旦在項(xiàng)目中的任何位置調(diào)用了Context的startServive()方法,相應(yīng)的服務(wù)就會(huì)得到執(zhí)行藕夫,并且回調(diào)onStartCommand()方法孽糖,如果服務(wù)第一次創(chuàng)建,那么onCreate()方法就會(huì)先于onStartCommand()方法執(zhí)行毅贮,
  2. 服務(wù)啟動(dòng)了就會(huì)一直保持運(yùn)行狀態(tài)办悟,直到stopService()或者是stopSelf()方法被調(diào)用,注意雖然每一次都是調(diào)用startServive()方法滩褥,但是每個(gè)服務(wù)都只會(huì)存在一個(gè)實(shí)例病蛉,只要調(diào)用一次stopService()或者是stopSelf()方法,服務(wù)就會(huì)停止下來
  3. 另外瑰煎,還可以調(diào)用Context的bindService()來獲取一個(gè)服務(wù)的持久連接铺然,這時(shí)就會(huì)回調(diào)服務(wù)中的onBind()方法,這時(shí)酒甸,如果服務(wù)第一次創(chuàng)建魄健,那么onCreate()方法就會(huì)先于onBind()方法執(zhí)行,之后就可以獲取到onBind()方法里返回的IBinder對(duì)象實(shí)例插勤,這樣就能自由的和服務(wù)進(jìn)行通信沽瘦,只要調(diào)用方和服務(wù)之間的連接沒有斷開,服務(wù)就會(huì)一直保持運(yùn)行狀態(tài)
  4. 當(dāng)調(diào)用startService()方法之后饮六,又去調(diào)用stopService()方法其垄,這是服務(wù)中的onDestroy()方法就會(huì)得到執(zhí)行,這個(gè)時(shí)候服務(wù)就銷毀了卤橄,類似的绿满,當(dāng)調(diào)用了bindService()方法之后,調(diào)用了unbindService()方法窟扑,服務(wù)中的onDestroy()方法就會(huì)得到執(zhí)行喇颁,這個(gè)時(shí)候服務(wù)就銷毀了
  5. 要注意的是漏健,對(duì)一個(gè)服務(wù)調(diào)用了startService(),又調(diào)用了bindService()方法之后橘霎,這個(gè)時(shí)候要調(diào)用stopService()和unbindService()方法蔫浆,onDestroy()方法才會(huì)執(zhí)行

服務(wù)的更多技巧

使用前臺(tái)服務(wù)

服務(wù)一般都是在后臺(tái)運(yùn)行的,當(dāng)系統(tǒng)出現(xiàn)內(nèi)存不足的時(shí)候姐叁,就有可能回收掉正在后臺(tái)運(yùn)行的服務(wù)瓦盛,如果想要服務(wù)一直保持運(yùn)行狀態(tài),而不會(huì)由于系統(tǒng)內(nèi)存不足的原因?qū)е卤换厥胀馇保涂梢钥紤]使用前臺(tái)服務(wù)了

  1. 前臺(tái)服務(wù)與普通服務(wù)最大的區(qū)別就是它會(huì)一直有一個(gè)正在運(yùn)行的圖標(biāo)在系統(tǒng)的狀態(tài)欄顯示原环,下拉可以看到更加詳細(xì)的信息,比如說天氣預(yù)報(bào)這種應(yīng)用处窥,一般都會(huì)在系統(tǒng)欄一直顯示當(dāng)前的天氣
  2. 創(chuàng)建一個(gè)前臺(tái)的服務(wù)嘱吗,修改MyService中的代碼
public class MyService extends Service {
    ...
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","onCreate executed");
        Intent intent = new Intent(this,MainActivity.class);
        PendingIntent p1 = PendingIntent.getActivity(this,0,intent,0);
        Notification notification = new NotificationCompat.Builder(this)
                .setContentText("this is title")
                .setContentText("thsi is content text")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                .setContentIntent(p1)
                .build();
        // 這里與之前不同
        startForeground(1,notification);
    }

    ...
}

  • 別的還保持不變,只需要修改onCreate()方法里的代碼就可以了滔驾,這些代碼就是之前學(xué)過的創(chuàng)建通知的方法
  • 只不過這里沒有使用 NotificationManager來將通知顯示出來谒麦,而是使用了 startForeground()方法,類似與notity()方法,第一個(gè)參數(shù)是通知id哆致,第二個(gè)參數(shù)是構(gòu)建的Notification對(duì)象绕德,調(diào)用這個(gè)startForeground()方法就會(huì)讓MyService變成一個(gè)前臺(tái)服務(wù),并在系統(tǒng)狀態(tài)欄顯示出來
  • 重新運(yùn)行程序沽瞭,點(diǎn)擊Start Service按鈕迁匠,MyService就會(huì)以前臺(tái)的模式啟動(dòng)了,并且在系統(tǒng)狀態(tài)欄會(huì)顯示一個(gè)通知的圖標(biāo)驹溃,下拉狀態(tài)欄就可以看到該通知的詳細(xì)內(nèi)容


    前臺(tái)服務(wù).png

使用IntentService

服務(wù)中的代碼都是默認(rèn)運(yùn)行在主線程當(dāng)中的城丧,如果直接在服務(wù)中處理一些耗時(shí)的邏輯,就容易出現(xiàn)ANR的情況豌鹤,所以這個(gè)時(shí)候就使用到了Android多線程編程技術(shù)了

  1. 我們應(yīng)該在服務(wù)的每個(gè)具體的方法里開啟一個(gè)子線程亡哄,然后在這里去處理一些耗時(shí)的邏輯,因此一個(gè)比較標(biāo)準(zhǔn)的服務(wù)就可以寫成
    @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);
    }

  • 但是這種服務(wù)一旦啟動(dòng)就會(huì)一直處于運(yùn)行的狀態(tài)布疙,必須調(diào)用stopService()或者stopSelf()方法才能讓服務(wù)停止下來蚊惯,所以想要實(shí)現(xiàn)讓一個(gè)服務(wù)在執(zhí)行完畢后自動(dòng)停止下來就可以這樣寫
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 處理具體的邏輯
                // 處理完邏輯,自動(dòng)停止下來
                stopSelf();
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

  • 但是這樣寫的話就太麻煩了灵临,這個(gè)時(shí)候ANdroid專門提供了一個(gè)IntentService類截型,這個(gè)類就可以解決前面遇到的麻煩
  1. 新建一個(gè)MyIntentServive類繼承自IntentServive
public class MyIntentServive extends IntentService {
    public MyIntentServive() {
        // 調(diào)用父類有參的構(gòu)造函數(shù),
        super("MyIntentServive");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        // 具體的邏輯操作
        // 打印當(dāng)前的線程的id
        Log.d("MyIntentService","Thread is "+Thread.currentThread().getId());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyIntentService","onDestroy executed");
    }

}

  • 首先提供一個(gè)無參的構(gòu)造函數(shù)儒溉,并且在內(nèi)部調(diào)用父類的有參構(gòu)造函數(shù)
  • 這里要注意的就是onHandleIntent()方法宦焦,這個(gè)方法已經(jīng)是在子線程中運(yùn)行的了,為了證實(shí),打印了當(dāng)前進(jìn)程的id波闹,而且這個(gè)服務(wù)在運(yùn)行結(jié)束后就會(huì)自動(dòng)的停止酝豪,在onDestroy()中也打印一句話
  1. 修改activity_main.xml中的代碼,加入一個(gè)MyIntentService這個(gè)服務(wù)的按鈕
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>

   ...
    <Button
        android:id="@+id/start_intent_Service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="MyIntentService"/>

</LinearLayout>
  1. 修改MainActivity中的代碼

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      ...
        Button startIntentService = (Button)findViewById(R.id.start_intent_Service);
        startIntentService.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
           ...
            case R.id.start_intent_Service:
            // 打印主線程id
                Log.d("MainActivity","Thread is "+ Thread.currentThread().getId());
                Intent intentService = new Intent(this,MyIntentServive.class);
                startService(intentService);
                break;
            default:
                break;
        }
    }
}

  1. 別忘了精堕,還要在AndroidManifest.xml中進(jìn)行注冊(cè)

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

    <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">
     ...
        <service android:name=".MyIntentServive" />

    </application>

</manifest>
  • 這個(gè)時(shí)候運(yùn)行程序孵淘,就會(huì)看到


    主頁面.png
  • 點(diǎn)擊MyIntentService按鈕,這個(gè)時(shí)候看打印的日志


    日志信息.png
  • 可以看到此時(shí)線程不同歹篓,而且onDestroy()方法也得到了執(zhí)行瘫证,說明是MyIntentService在運(yùn)行完畢后自動(dòng)停止了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市滋捶,隨后出現(xiàn)的幾起案子痛悯,更是在濱河造成了極大的恐慌,老刑警劉巖重窟,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異惧财,居然都是意外死亡巡扇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門垮衷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厅翔,“玉大人,你說我怎么就攤上這事搀突〉睹疲” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵仰迁,是天一觀的道長(zhǎng)甸昏。 經(jīng)常有香客問我,道長(zhǎng)徐许,這世上最難降的妖魔是什么施蜜? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮雌隅,結(jié)果婚禮上翻默,老公的妹妹穿的比我還像新娘。我一直安慰自己恰起,他們只是感情好修械,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著检盼,像睡著了一般肯污。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天仇箱,我揣著相機(jī)與錄音县恕,去河邊找鬼。 笑死剂桥,一個(gè)胖子當(dāng)著我的面吹牛忠烛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播权逗,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼美尸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了斟薇?” 一聲冷哼從身側(cè)響起师坎,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎堪滨,沒想到半個(gè)月后胯陋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袱箱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年遏乔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片发笔。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盟萨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出了讨,到底是詐尸還是另有隱情捻激,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布前计,位于F島的核電站胞谭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏残炮。R本人自食惡果不足惜韭赘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望势就。 院中可真熱鬧泉瞻,春花似錦、人聲如沸苞冯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舅锄。三九已至鞭达,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背畴蹭。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工坦仍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叨襟。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓繁扎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親糊闽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子梳玫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容