Android Service學(xué)習(xí)筆記

參考:
Android Service完全解析弧蝇,關(guān)于服務(wù)你所需知道的一切(上)
Android Service完全解析,關(guān)于服務(wù)你所需知道的一切(下)
關(guān)于Android Service真正的完全詳解,你需要知道的一切
閱讀了這兩(三)篇解析之后,將其中涉及到的東西以自己能理解的方式記錄下來。


介紹

Service主要用于在后臺處理一些耗時的邏輯谭确,或者去執(zhí)行某些需要長期運行的任務(wù)。必要的時候我們甚至可以在程序退出的情況下票渠,讓Service在后臺繼續(xù)保持運行狀態(tài)逐哈,如音樂播放器等。
根據(jù)服務(wù)在主線程或其他線程運行问顷,可以分為本地服務(wù)和遠程服務(wù)昂秃;

啟動與綁定

根據(jù)服務(wù)運行的兩種形式,可以分為啟動方式和綁定方式:

  • 啟動
    當(dāng)應(yīng)用組件(如 Activity)通過調(diào)用 startService() 啟動服務(wù)時杜窄,服務(wù)即處于“啟動”狀態(tài)肠骆。一旦啟動,服務(wù)即可在后臺無限期運行塞耕,即使啟動服務(wù)的組件已被銷毀也不受影響蚀腿,除非手動調(diào)用才能停止服務(wù), 已啟動的服務(wù)通常是執(zhí)行單一操作扫外,而且不會將結(jié)果返回給調(diào)用方莉钙,和啟動源沒什么聯(lián)系。
  • 綁定
    當(dāng)應(yīng)用組件通過調(diào)用bindService() 綁定到服務(wù)時筛谚,服務(wù)即處于“綁定”狀態(tài)磁玉。綁定服務(wù)提供了一個客戶端-服務(wù)器接口(ServiceConnection),通過這個借口中的相關(guān)方法可以獲取到服務(wù)的信息驾讲,執(zhí)行相關(guān)方法等蜀涨,允許組件與服務(wù)進行交互、發(fā)送請求蝎毡、獲取結(jié)果厚柳,甚至是利用進程間通信 (IPC) 跨進程執(zhí)行這些操作。 僅當(dāng)與另一個應(yīng)用組件綁定時沐兵,綁定服務(wù)才會運行别垮。 多個組件可以同時綁定到該服務(wù),但全部取消綁定后扎谎,該服務(wù)即會被銷毀碳想。

雖然服務(wù)的狀態(tài)有啟動和綁定兩種,但實際上一個服務(wù)可以同時是這兩種狀態(tài)毁靶,也就是說胧奔,它既可以是啟動服務(wù)(以無限期運行),也可以是綁定服務(wù)服務(wù)预吆,問題只是在于是否實現(xiàn)了相應(yīng)的回調(diào)方法:onStartCommand()(允許組件啟動服務(wù))和 onBind()(允許綁定服務(wù))龙填。有點需要注意的是Android系統(tǒng)僅會為一個Service創(chuàng)建一個實例對象,所以不管是啟動服務(wù)還是綁定服務(wù),操作的是同一個Service實例岩遗,而且由于綁定服務(wù)或者啟動服務(wù)執(zhí)行順序問題將會出現(xiàn)以下兩種情況:

  • 先綁定服務(wù)后啟動服務(wù)
    如果當(dāng)前Service實例先以綁定狀態(tài)運行扇商,然后再以啟動狀態(tài)運行,那么綁定服務(wù)將會轉(zhuǎn)為啟動服務(wù)運行宿礁,這時如果之前綁定的宿主(Activity)被銷毀了案铺,也不會影響服務(wù)的運行,服務(wù)還是會一直運行下去梆靖,指定收到調(diào)用停止服務(wù)或者內(nèi)存不足時才會銷毀該服務(wù)控汉。
  • 先啟動服務(wù)后綁定服務(wù)
    如果當(dāng)前Service實例先以啟動狀態(tài)運行,然后再以綁定狀態(tài)運行返吻,當(dāng)前啟動服務(wù)并不會轉(zhuǎn)為綁定服務(wù)姑子,但是還是會與宿主綁定,只是即使宿主解除綁定后思喊,服務(wù)依然按啟動服務(wù)的生命周期在后臺運行壁酬,直到有Context調(diào)用了stopService()或是服務(wù)本身調(diào)用了stopSelf()方法抑或內(nèi)存不足時才會銷毀服務(wù)次酌。

生命周期

生命周期

使用方法

Service有幾種不同的運行方式恨课,可以在主線程或其他線程中運行,可以跨進程交互岳服,但整體來說不外乎在Service中編寫相對應(yīng)的回調(diào)方法剂公,然后在Activity中啟動或綁定,如果只是啟動吊宋,則之后Activity只能停止纲辽,而不能做出交互,只有綁定方式璃搜,才可以在ServiceConnection中獲取到Service定義的Binder對象(或者Service自己也是可以的)進行交互拖吼。

繼承Service編寫自己的自定義Service

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        // 只在啟動模式下執(zhí)行
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  
      
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        // 只在綁定時執(zhí)行,需要編寫B(tài)inder對象在這里返回
        return null;  
    }  
  
}  

啟動模式

  • AndroidManifest.xml中注冊(application標(biāo)簽之內(nèi))
    <service android:name="com.example.servicetest.MyService" >
  • 在需要的時機使用Intent啟動或停止Service
    Intent startIntent = new Intent(this, MyService.class);  
    startService(startIntent);  
    Intent stopIntent = new Intent(this, MyService.class);  
    stopService(stopIntent);  

因為編寫的Service沒有編寫onBind()方法这吻,也沒有綁定任何東西吊档,啟動之后就和啟動它的Activity沒有什么關(guān)系了;
啟動過程:onCreate()->onStartCommand()唾糯,在啟動之后再startService怠硼,就只有onStartCommand()
執(zhí)行了。
在服務(wù)的內(nèi)部可以調(diào)用stopSelf()方法停止當(dāng)前服務(wù)移怯。

綁定模式

要和Activity關(guān)聯(lián)起來就需要實現(xiàn)onBind()方法香璃,首先需要編寫一個自定義的Binder繼承自Binder基類:

class MyBinder extends Binder {  
    public void startDoSth() {  
        Log.d("TAG", "do sth");  
        // do sth  
    }  
}  

這個類將在Service對象創(chuàng)建時實例化并用于和Service綁定,修改之前的Service代碼:

private MyBinder mBinder = new MyBinder();
...
...
@Override  
public IBinder onBind(Intent intent) {  
    // 此處把mBinder作為一個IBinder返回舟误,在后面被connection獲取
    return mBinder;  
}  

同時在Activity中還需要實現(xiàn)一個ServiceConnection來獲取Binder并執(zhí)行里面的方法完成這一過程:

private MyService.MyBinder myBinder;  
private ServiceConnection connection = new ServiceConnection() {  
    @Override  
    public void onServiceDisconnected(ComponentName name) {  
        //Android 系統(tǒng)會在與服務(wù)的連接意外中斷時(例如當(dāng)服務(wù)崩潰或被終止時)調(diào)用該方法葡秒。注意:當(dāng)客戶端取消綁定時,系統(tǒng)“絕對不會”調(diào)用該方法。
    }  
  
    @Override  
    public void onServiceConnected(ComponentName name, IBinder service) { 
        // 綁定之后進行的操作同云,應(yīng)該是自動獲取到IBinder類型的service糖权,實際上就是MyBinder,所以直接強制類型轉(zhuǎn)換
        myBinder = (MyService.MyBinder) service;  
        myBinder.startDoSth();  
        }  
    };  

到這里只是寫好了用于綁定的準(zhǔn)備工作和綁定完成之后的操作炸站,而真正的綁定過程如下:

Intent bindIntent = new Intent(this, MyService.class);  
bindService(bindIntent, connection, BIND_AUTO_CREATE); 

bindService()方法接收三個參數(shù)星澳,第一個參數(shù)就是剛剛構(gòu)建出的Intent對象,第二個參數(shù)是前面創(chuàng)建出的ServiceConnection的實例旱易,第三個參數(shù)是一個標(biāo)志位禁偎,這里傳入BIND_AUTO_CREATE表示在Activity和Service建立關(guān)聯(lián)后自動創(chuàng)建Service,這會使得MyService中的onCreate()方法得到執(zhí)行阀坏,但onStartCommand()方法不會執(zhí)行如暖。所以綁定之后的流程是onCreate()->startDoSth()
注意到這里并沒有onStartCommand()忌堂,而是執(zhí)行onServiceConnected()中的代碼盒至。
停止Service:

unbindService(connection);
// 這里的service只創(chuàng)建了,并沒有start士修,所以直接解綁就可以

注意:
Stop Service只會讓Service停止枷遂,Unbind Service按鈕只會讓Service和Activity解除關(guān)聯(lián),一個Service必須要在既沒有和任何Activity關(guān)聯(lián)又處理停止?fàn)顟B(tài)的時候才會被銷毀棋嘲。
宿主(Activity)解除綁定后酒唉,綁定服務(wù)就會被銷毀

遠程Service(無法綁定)

將一個普通的Service轉(zhuǎn)換成遠程Service其實非常簡單,只需要在注冊Service的時候?qū)⑺腶ndroid:process屬性指定成:remote就可以了

<service  
    android:name="com.example.servicetest.MyService"  
    android:process=":remote" >  
</service>  

遠程Service不在主線程中運行沸移,耗時操作不會阻塞進程痪伦,但是Activity和Service運行在兩個不同的進程當(dāng)中,也就不能再使用傳統(tǒng)的建立關(guān)聯(lián)的方式雹锣,根本無法綁定了网沾。所以這時只能start而不能使用bind方法來使用Service。

綁定遠程Service(改進版/跨進程通信)

使用AIDL

此處使用了AIDL(Android Interface Definition Language)蕊爵,是Android接口定義語言的意思辉哥,它可以用于讓某個Service與多個應(yīng)用程序組件之間進行跨進程通信,從而可以實現(xiàn)多個應(yīng)用程序共享同一個Service的功能在辆。
新建aidl证薇,之后會自動生成這樣一個java文件:

package com.example.servicetest;  
interface MyAIDLService {  
    int plus(int a, int b);  
    String toUpperCase(String str);  
}

然后修改MyService中的代碼,在里面實現(xiàn)定義好的MyAIDLService接口(沒弄明白Stub哪來的匆篓,此處理解為一個存根)浑度,此處把實例化Binder改成了實例化一個Stub:

MyAIDLService.Stub mBinder = new Stub() {  
    @Override  
    public String toUpperCase(String str) throws RemoteException {  
        if (str != null) {  
            return str.toUpperCase();  
        }  
        return null;  
    }  

    @Override  
    public int plus(int a, int b) throws RemoteException {  
        return a + b;  
    }  
};  

然后在onBind()方法中將MyAIDLService.Stub的實現(xiàn)返回。因為Stub其實就是Binder的子類鸦概,所以在onBind()方法中可以直接返回Stub的實現(xiàn)箩张。
修改connection:

@Override  
public void onServiceConnected(ComponentName name, IBinder service) {  
      myAIDLService = MyAIDLService.Stub.asInterface(service);  
      // 調(diào)用Service中的方法
      try {  
          int result = myAIDLService.plus(3, 5);  
          String upperStr = myAIDLService.toUpperCase("hello world");  
          Log.d("TAG", "result is " + result);  
          Log.d("TAG", "upperStr is " + upperStr);  
      } catch (RemoteException e) {  
          e.printStackTrace();  
      }  
} 

關(guān)于Stub:
j2ee里面的stub是這樣說的..為屏蔽客戶調(diào)用遠程主機上的對象甩骏,必須提供某種方式來模擬本地對象,這種本地對象稱為存根(stub),存根負責(zé)接收本地方法調(diào)用,并將它們委派給各自的具體實現(xiàn)對象

此時依然是調(diào)用bindService()來綁定服務(wù),在一個Activity里調(diào)用了同一個應(yīng)用程序的Service里的方法先慷。

跨進程

在另一個應(yīng)用程序中去綁定Service的時候并沒有MyService這個類饮笛,這時就必須使用到隱式Intent了。現(xiàn)在修改AndroidManifest.xml中的代碼论熙,給MyService加上一個action

<service  
    android:name="com.example.servicetest.MyService"  
    android:process=":remote" >  
    <intent-filter>  
        <action android:name="com.example.servicetest.MyAIDLService"/>  
    </intent-filter>  
</service>  

在另一個程序中福青,需要復(fù)制一份MyAIDLService.aidl文件,注意要將原有的包路徑一起拷貝過來脓诡,綁定的代碼修改如下:

Intent intent = new Intent("com.example.servicetest.MyAIDLService").setPakage("com.example.servicetest");;  
bindService(intent, connection, BIND_AUTO_CREATE);  

將Intent的action指定成了com.example.servicetest.MyAIDLService无午。

使用Messenger

  1. 服務(wù)實現(xiàn)一個 Handler,由其接收來自客戶端的每個調(diào)用的回調(diào)
 /**
 * 用于接收從客戶端傳遞過來的數(shù)據(jù)
 */
class IncomingHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_SAY_HELLO:
                Log.i(TAG, "thanks,Service had receiver message from client!");
                break;
            default:
                super.handleMessage(msg);
        }
    }
}
  1. Handler 用于創(chuàng)建 Messenger 對象(對 Handler 的引用)
/**
* 創(chuàng)建Messenger并傳入Handler實例對象
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
  1. Messenger 創(chuàng)建一個 IBinder祝谚,服務(wù)通過 onBind() 使其返回客戶端
/**
 * 當(dāng)綁定Service時,該方法被調(diào)用,將通過mMessenger返回一個實現(xiàn)
 * IBinder接口的實例對象
 */
@Override
public IBinder onBind(Intent intent) {
    Log.i(TAG, "Service is invoke onBind");
    return mMessenger.getBinder();
}
  1. 客戶端使用 IBinder 將 Messenger(引用服務(wù)的 Handler)實例化宪迟,然后使用Messenger將 Message 對象發(fā)送給服務(wù)
public void onServiceConnected(ComponentName className, IBinder service) {
    /**
     * 通過服務(wù)端傳遞的IBinder對象,創(chuàng)建相應(yīng)的Messenger
     * 通過該Messenger對象與服務(wù)端進行交互
     */
    mService = new Messenger(service);
    mBound = true;
}
  1. 服務(wù)在其 Handler 中(在 handleMessage() 方法中)接收每個 Message

前臺服務(wù)

前臺服務(wù)被認為是用戶主動意識到的一種服務(wù),因此在內(nèi)存不足時交惯,系統(tǒng)也不會考慮將其終止次泽。 前臺服務(wù)必須為狀態(tài)欄提供通知,狀態(tài)欄位于“正在進行”標(biāo)題下方席爽,這意味著除非服務(wù)停止或從前臺刪除意荤,否則不能清除通知。
Android官方給我們提供了兩個方法拳昌,分別是startForeground()和stopForeground()袭异,這兩個方式解析如下:

  • startForeground(int id, Notification notification)
    該方法的作用是把當(dāng)前服務(wù)設(shè)置為前臺服務(wù)钠龙,其中id參數(shù)代表唯一標(biāo)識通知的整型數(shù)炬藤,需要注意的是提供給 startForeground() 的整型 ID 不得為 0,而notification是一個狀態(tài)欄的通知碴里。
  • stopForeground(boolean removeNotification)
    該方法是用來從前臺刪除服務(wù)沈矿,此方法傳入一個布爾值,指示是否也刪除狀態(tài)欄通知咬腋,true為刪除羹膳。 注意該方法并不會停止服務(wù)。 但是根竿,如果在服務(wù)正在前臺運行時將其停止陵像,則通知也會被刪除。
    Myservice.java
 /**
 * Notification
 */
public void createNotification(){
    //使用兼容版本
    NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
    //設(shè)置狀態(tài)欄的通知圖標(biāo)
    builder.setSmallIcon(R.mipmap.ic_launcher);
    //設(shè)置通知欄橫條的圖標(biāo)
    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.screenflash_logo));
    //禁止用戶點擊刪除按鈕刪除
    builder.setAutoCancel(false);
    //禁止滑動刪除
    builder.setOngoing(true);
    //右上角的時間顯示
    builder.setShowWhen(true);
    //設(shè)置通知欄的標(biāo)題內(nèi)容
    builder.setContentTitle("I am Foreground Service!!!");
    //創(chuàng)建通知
    Notification notification = builder.build();
    //設(shè)置為前臺服務(wù)
    startForeground(NOTIFICATION_DOWNLOAD_PROGRESS_ID,notification);
}

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    int i=intent.getExtras().getInt("cmd");
    if(i==0){
        if(!isRemove) {
            createNotification();
        }
        isRemove=true;
    }else {
        //移除前臺服務(wù)
        if (isRemove) {
            stopForeground(true);
        }
        isRemove=false;
    }

    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
    //移除前臺服務(wù)
    if (isRemove) {
        stopForeground(true);
    }
    isRemove=false;
    super.onDestroy();
}

onStartCommand詳解

onStartCommand(tent intent, int flags, int startId)

參數(shù)

  • intent :啟動時寇壳,啟動組件傳遞過來的Intent醒颖,如Activity可利用Intent封裝所需要的參數(shù)并傳遞給Service
  • flags:表示啟動請求時是否有額外數(shù)據(jù),可選值有 0壳炎,START_FLAG_REDELIVERY泞歉,START_FLAG_RETRY,0代表沒有,它們具體含義如下:
  • START_FLAG_REDELIVERY
    這個值代表了onStartCommand方法的返回值為
    START_REDELIVER_INTENT腰耙,而且在上一次服務(wù)被殺死前會去調(diào)用stopSelf方法停止服務(wù)榛丢。其中START_REDELIVER_INTENT意味著當(dāng)Service因內(nèi)存不足而被系統(tǒng)kill后,則會重建服務(wù)挺庞,并通過傳遞給服務(wù)的最后一個 Intent 調(diào)用 onStartCommand()晰赞,此時Intent時有值的。
  • START_FLAG_RETRY
    該flag代表當(dāng)onStartCommand調(diào)用后一直沒有返回值時选侨,會嘗試重新去調(diào)用onStartCommand()宾肺。
  • startId : 指明當(dāng)前服務(wù)的唯一ID,與stopSelfResult(int startId)配合使用侵俗,stopSelfResult 可以更安全地根據(jù)ID停止服務(wù)锨用。

返回值

實際上onStartCommand的返回值int類型才是最最值得注意的,它有三種可選值隘谣, START_STICKY增拥,START_NOT_STICKYSTART_REDELIVER_INTENT寻歧,它們具體含義如下:

  • START_STICKY
    當(dāng)Service因內(nèi)存不足而被系統(tǒng)kill后掌栅,一段時間后內(nèi)存再次空閑時,系統(tǒng)將會嘗試重新創(chuàng)建此Service码泛,一旦創(chuàng)建成功后將回調(diào)onStartCommand方法猾封,但其中的Intent將是null,除非有掛起的Intent噪珊,如pendingintent晌缘,這個狀態(tài)下比較適用于不執(zhí)行命令、但無限期運行并等待作業(yè)的媒體播放器或類似服務(wù)痢站。
  • START_NOT_STICKY
    當(dāng)Service因內(nèi)存不足而被系統(tǒng)kill后磷箕,即使系統(tǒng)內(nèi)存再次空閑時,系統(tǒng)也不會嘗試重新創(chuàng)建此Service阵难。除非程序中再次調(diào)用startService啟動此Service岳枷,這是最安全的選項,可以避免在不必要時以及應(yīng)用能夠輕松重啟所有未完成的作業(yè)時運行服務(wù)呜叫。
  • START_REDELIVER_INTENT
    當(dāng)Service因內(nèi)存不足而被系統(tǒng)kill后空繁,則會重建服務(wù),并通過傳遞給服務(wù)的最后一個 Intent 調(diào)用 onStartCommand()朱庆,任何掛起 Intent均依次傳遞盛泡。與START_STICKY不同的是,其中的傳遞的Intent將是非空椎工,是最后一次調(diào)用startService中的intent饭于。這個值適用于主動執(zhí)行應(yīng)該立即恢復(fù)的作業(yè)(例如下載文件)的服務(wù)蜀踏。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掰吕,隨后出現(xiàn)的幾起案子果覆,更是在濱河造成了極大的恐慌,老刑警劉巖殖熟,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件局待,死亡現(xiàn)場離奇詭異,居然都是意外死亡菱属,警方通過查閱死者的電腦和手機钳榨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纽门,“玉大人薛耻,你說我怎么就攤上這事∩土辏” “怎么了饼齿?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蝙搔。 經(jīng)常有香客問我缕溉,道長,這世上最難降的妖魔是什么吃型? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任证鸥,我火速辦了婚禮,結(jié)果婚禮上勤晚,老公的妹妹穿的比我還像新娘枉层。我一直安慰自己,他們只是感情好运翼,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布返干。 她就那樣靜靜地躺著兴枯,像睡著了一般血淌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上财剖,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天悠夯,我揣著相機與錄音,去河邊找鬼躺坟。 笑死沦补,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咪橙。 我是一名探鬼主播夕膀,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虚倒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了产舞?” 一聲冷哼從身側(cè)響起魂奥,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎易猫,沒想到半個月后耻煤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡准颓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年哈蝇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片攘已。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡炮赦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出样勃,到底是詐尸還是另有隱情眼五,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布彤灶,位于F島的核電站看幼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏幌陕。R本人自食惡果不足惜诵姜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搏熄。 院中可真熱鬧棚唆,春花似錦、人聲如沸心例。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽止后。三九已至瞎惫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間译株,已是汗流浹背瓜喇。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留歉糜,地道東北人乘寒。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像匪补,于是被迫代替她去往敵國和親伞辛。 傳聞我的和親對象是個殘疾皇子烂翰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

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

  • 前言:本文所寫的是博主的個人見解,如有錯誤或者不恰當(dāng)之處蚤氏,歡迎私信博主刽酱,加以改正!原文鏈接瞧捌,demo鏈接 Serv...
    PassersHowe閱讀 1,415評論 0 5
  • 上篇我們講解了Android中的5中等級的進程棵里,分別是:前臺進程、可見進程姐呐、服務(wù)進程殿怜、后臺進程、空進程曙砂。系統(tǒng)會按照...
    徐愛卿閱讀 3,857評論 6 33
  • [文章內(nèi)容來自Developers] Service是一個可以在后臺執(zhí)行長時間運行操作而不提供用戶界面的應(yīng)用組件头谜。...
    岳小川閱讀 866評論 0 7
  • 花之國有許多花,而花和花的工作時間不同鸠澈,有的春天工作柱告、有的夏天工作、有的秋天工作笑陈、還有的冬天工作际度。為了讓所有的花記...
    做作業(yè)的麥子媽閱讀 271評論 1 4
  • 孤獨,從來都是我用來保護自己的利器涵妥,我從來不相信任何人也不敢去相信這所謂的感情世界乖菱,太虛假做作和物質(zhì)。 生活蓬网,...
    柔冰雨閱讀 217評論 4 0