四大組件之Service_綁定服務

[文章內(nèi)容來自Developers]

綁定服務是客戶端-服務器接口中的服務器驶冒。綁定服務可讓組件(例如 Activity)綁定到服務殊轴、發(fā)送請求嚎杨、接收響應蓄喇,甚至執(zhí)行進程間通信 (IPC)发侵。 綁定服務通常只在為其他應用組件服務時處于活動狀態(tài),不會無限期在后臺運行妆偏。

基礎知識


綁定服務是 Service類的實現(xiàn)刃鳄,可讓其他應用與其綁定和交互。要提供服務綁定钱骂,您必須實現(xiàn) onBind()回調(diào)方法叔锐。該方法返回的 IBinder對象定義了客戶端用來與服務進行交互的編程接口。

客戶端可通過調(diào)用 bindService()綁定到服務见秽。調(diào)用時愉烙,它必須提供 ServiceConnection的實現(xiàn),后者會監(jiān)控與服務的連接张吉。bindService()方法會立即無值返回齿梁,但當 Android 系統(tǒng)創(chuàng)建客戶端與服務之間的連接時,會對 ServiceConnection調(diào)用 onServiceConnected()肮蛹,向客戶端傳遞用來與服務通信的 IBinder勺择。
多個客戶端可同時連接到一個服務。不過伦忠,只有在第一個客戶端綁定時省核,系統(tǒng)才會調(diào)用服務的onBind()方法來檢索 IBinder。系統(tǒng)隨后無需再次調(diào)用 onBind()昆码,便可將同一 IBinder傳遞至任何其他綁定的客戶端气忠。
當最后一個客戶端取消與服務的綁定時,系統(tǒng)會將服務銷毀(除非 startService()也啟動了該服務)赋咽。
當您實現(xiàn)綁定服務時旧噪,最重要的環(huán)節(jié)是定義您的 onBind() 回調(diào)方法返回的接口。您可以通過幾種不同的方法定義服務的 IBinder 接口脓匿,下文對這些方法逐一做了闡述淘钟。

創(chuàng)建綁定服務


創(chuàng)建提供綁定的服務時,您必須提供 IBinder陪毡,用以提供客戶端用來與服務進行交互的編程接口米母。 您可以通過三種方法定義接口:

擴展 Binder 類
如果服務是供您的自有應用專用勾扭,并且在與客戶端相同的進程中運行(常見情況),則應通過擴展 Binder類并從 onBind()返回它的一個實例來創(chuàng)建接口铁瞒∶钌客戶端收到 Binder 后,可利用它直接訪問 Binder 實現(xiàn)中乃至 Service中可用的公共方法慧耍。如果服務只是您的自有應用的后臺工作線程身辨,則優(yōu)先采用這種方法。 不以這種方式創(chuàng)建接口的唯一原因是芍碧,您的服務被其他應用或不同的進程占用栅表。

使用 Messenger
如需讓接口跨不同的進程工作,則可使用 Messenger為服務創(chuàng)建接口师枣。服務可以這種方式定義對應于不同類型 Message 對象的 Handler。此 Handler是 Messenger的基礎萧落,后者隨后可與客戶端分享一個 IBinder践美,從而讓客戶端能利用 Message對象向服務發(fā)送命令。此外找岖,客戶端還可定義自有 Messenger陨倡,以便服務回傳消息。這是執(zhí)行進程間通信 (IPC) 的最簡單方法许布,因為 Messenger 會在單一線程中創(chuàng)建包含所有請求的隊列兴革,這樣您就不必對服務進行線程安全設計。

使用 AIDL
AIDL(Android 接口定義語言)執(zhí)行所有將對象分解成原語的工作蜜唾,操作系統(tǒng)可以識別這些原語并將它們編組到各進程中杂曲,以執(zhí)行 IPC。 之前采用 Messenger的方法實際上是以 AIDL 作為其底層結構袁余。 如上所述擎勘,Messenger會在單一線程中創(chuàng)建包含所有客戶端請求的隊列,以便服務一次接收一個請求颖榜。 不過棚饵,如果您想讓服務同時處理多個請求,則可直接使用 AIDL掩完。 在此情況下噪漾,您的服務必須具備多線程處理能力,并采用線程安全式設計且蓬。如需直接使用 AIDL欣硼,您必須創(chuàng)建一個定義編程接口的 .aidl文件。Android SDK 工具利用該文件生成一個實現(xiàn)接口并處理 IPC 的抽象類缅疟,您隨后可在服務內(nèi)對其進行擴展分别。

:大多數(shù)應用“都不會”使用 AIDL 來創(chuàng)建綁定服務遍愿,因為它可能要求具備多線程處理能力,并可能導致實現(xiàn)的復雜性增加耘斩。因此沼填,AIDL 并不適合大多數(shù)應用,本文也不會闡述如何將其用于您的服務括授。如果您確定自己需要直接使用 AIDL坞笙,請參閱 AIDL 文檔。

綁定到已啟動服務
正如服務文檔中所述荚虚,您可以創(chuàng)建同時具有已啟動和綁定兩種狀態(tài)的服務薛夜。 也就是說,可通過調(diào)用startService()啟動該服務版述,讓服務無限期運行梯澜;此外,還可通過調(diào)用 bindService()使客戶端綁定到服務渴析。
如果您確實允許服務同時具有已啟動和綁定狀態(tài)晚伙,則服務啟動后,系統(tǒng)“不會”在所有客戶端都取消綁定時銷毀服務俭茧。 為此咆疗,您必須通過調(diào)用stopSelf()或 stopService()顯式停止服務。
盡管您通常應該實現(xiàn) onBind()onStartCommand()母债,但有時需要同時實現(xiàn)這兩者午磁。例如,音樂播放器可能發(fā)現(xiàn)讓其服務無限期運行并同時提供綁定很有用處毡们。 這樣一來迅皇,Activity 便可啟動服務進行音樂播放,即使用戶離開應用漏隐,音樂播放也不會停止喧半。 然后,當用戶返回應用時青责,Activity 可綁定到服務挺据,重新獲得回放控制權。
請務必閱讀管理綁定服務的生命周期部分脖隶,詳細了解有關為已啟動服務添加綁定時該服務的生命周期信息扁耐。

擴展 Binder 類
如果您的服務僅供本地應用使用,不需要跨進程工作产阱,則可以實現(xiàn)自有 Binder類婉称,讓您的客戶端通過該類直接訪問服務中的公共方法。

:此方法只有在客戶端和服務位于同一應用和進程內(nèi)這一最常見的情況下方才有效。 例如王暗,對于需要將 Activity 綁定到在后臺播放音樂的自有服務的音樂應用悔据,此方法非常有效。

以下是具體的設置方法:
1.在您的服務中俗壹,創(chuàng)建一個可滿足下列任一要求的 Binder實例:包含客戶端可調(diào)用的公共方法返回當前 Service實例科汗,其中包含客戶端可調(diào)用的公共方法或返回由服務承載的其他類的實例,其中包含客戶端可調(diào)用的公共方法
2.從 onBind()回調(diào)方法返回此 Binder實例绷雏。
3.在客戶端中头滔,從 onServiceConnected()回調(diào)方法接收 Binder,并使用提供的方法調(diào)用綁定服務涎显。

:之所以要求服務和客戶端必須在同一應用內(nèi)坤检,是為了便于客戶端轉(zhuǎn)換返回的對象和正確調(diào)用其 API。服務和客戶端還必須在同一進程內(nèi)期吓,因為此方法不執(zhí)行任何跨進程編組早歇。

例如,以下這個服務可讓客戶端通過 Binder實現(xiàn)訪問服務中的方法:

public class LocalService extends Service {    
// Binder given to clients    
private final IBinder mBinder = new LocalBinder();    
// Random number generator    
private final Random mGenerator = new Random();    
/**     
* Class used for the client Binder.  Because we know this service always     
* runs in the same process as its clients, we don't need to deal with IPC.     
*/    
public class LocalBinder extends Binder {        
LocalService getService() {            
// Return this instance of LocalService so clients can call public methods            
return LocalService.this;        
}    
}    
@Override
    public IBinder onBind(Intent intent) {        
return mBinder;
    }    
/** method for clients */    
public int getRandomNumber() {      
return mGenerator.nextInt(100);    
}
}

LocalBinder為客戶端提供 getService()方法讨勤,以檢索 LocalService
的當前實例缺前。這樣,客戶端便可調(diào)用服務中的公共方法悬襟。 例如,客戶端可調(diào)用服務中的 getRandomNumber()拯刁。
點擊按鈕時脊岳,以下這個 Activity 會綁定到 LocalService并調(diào)用 getRandomNumber():

public class BindingActivity extends Activity {    
LocalService mService;    
boolean mBound = false;    
@Override    
protected void onCreate(Bundle savedInstanceState) {        
super.onCreate(savedInstanceState);        
setContentView(R.layout.main);    
}    
@Override    
protected void onStart() {        
super.onStart();        
// Bind to LocalService        
Intent intent = new Intent(this, LocalService.class);        
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);    
}    
@Override    
protected void onStop() {        
super.onStop();        
// Unbind from the service        
if (mBound) {            
unbindService(mConnection);            
mBound = false;        
}    
}    
/** Called when a button is clicked (the button in the layout file attaches to      
* this method with the android:onClick attribute) 
*/    
public void onButtonClick(View v) {        
if (mBound) {            
// Call a method from the LocalService.            
// However, if this call were something that might hang, then this request should            
// occur in a separate thread to avoid slowing down the activity performance.            
int num = mService.getRandomNumber();            
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();        
}    
}    
/** Defines callbacks for service binding, passed to bindService() 
*/    
private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {            
// We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }
        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

上例說明了客戶端如何使用 ServiceConnection的實現(xiàn)和 onServiceConnected() 回調(diào)綁定到服務。下文更詳細介紹了綁定到服務的過程垛玻。

:在上例中割捅,onStop() 方法將客戶端與服務取消綁定惧互。 客戶端應在適當時機與服務取消綁定在辆,如附加說明中所述景醇。

如需查看更多示例代碼宵距,請參見 ApiDemos 中的 LocalService.java
類和 LocalServiceActivities.java
類谆构。

使用 Messenger

與 AIDL 比較當您需要執(zhí)行 IPC 時愁溜,為您的接口用 Messenger要比使用 AIDL 實現(xiàn)它更加簡單逼争,因為 Messenger 會將所有服務調(diào)用排入隊列搓蚪,而純粹的 AIDL 接口會同時向服務發(fā)送多個請求郭蕉,服務隨后必須應對多線程處理疼邀。
對于大多數(shù)應用,服務不需要執(zhí)行多線程處理召锈,因此使用 Messenger可讓服務一次處理一個調(diào)用旁振。如果您的服務必須執(zhí)行多線程處理,則應使用 AIDL來定義接口。

如需讓服務與遠程進程通信拐袜,則可使用 Messenger為您的服務提供接口吉嚣。利用此方法,您無需使用 AIDL 便可執(zhí)行進程間通信 (IPC)蹬铺。
以下是 Messenger的使用方法摘要:

  • 服務實現(xiàn)一個 Handler尝哆,由其接收來自客戶端的每個調(diào)用的回調(diào)
  • Handler 用于創(chuàng)建 Messenger對象(對 Handler的引用)
  • Messenger 創(chuàng)建一個 IBinder,服務通過 onBind()使其返回客戶端
  • 客戶端使用 IBinder將 Messenger(引用服務的 Handler)實例化丛塌,然后使用后者將 Message對象發(fā)送給服務
  • 服務在其 Handler 中(具體地講较解,是在 handleMessage()方法中)接收每個 Message。

這樣赴邻,客戶端并沒有調(diào)用服務的“方法”印衔。而客戶端傳遞的“消息”(Message對象)是服務在其 Handler中接收的。
以下是一個使用 Messenger 接口的簡單服務示例:

public class MessengerService extends Service {
    /** Command to the service to display a message */ 
   static final int MSG_SAY_HELLO = 1;
    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) { 
               case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg); 
           }
        }
    }
    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */ 
   final Messenger mMessenger = new Messenger(new IncomingHandler());
    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}

請注意姥敛,服務就是在 Handler的 handleMessage()方法中接收傳入的 Message奸焙,并根據(jù) what成員決定下一步操作。
客戶端只需根據(jù)服務返回的 IBinder 創(chuàng)建一個 Messenger彤敛,然后利用 send()發(fā)送一條消息与帆。例如,以下就是一個綁定到服務并向服務傳遞MSG_SAY_HELLO消息的簡單 Activity:

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;
    /** Flag indicating whether we have called bind on the service. */
    boolean mBound;
    /**
     * Class for interacting with the main interface of the service.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = new Messenger(service);
            mBound = true;
        }
        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound = false;
        }
    };
    public void sayHello(View v) {
        if (!mBound) return;
        // Create and send a message to the service, using a supported 'what' value
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    @Override
    protected void onStart() {
        super.onStart();
        // Bind to the service
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }
    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

請注意墨榄,此示例并未說明服務如何對客戶端作出響應玄糟。如果您想讓服務作出響應,則還需要在客戶端中創(chuàng)建一個 Messenger袄秩。然后阵翎,當客戶端收到 onServiceConnected()回調(diào)時,會向服務發(fā)送一條 Message之剧,并在其 send()方法的 replyTo參數(shù)中包含客戶端的 Messenger郭卫。

綁定到服務


應用組件(客戶端)可通過調(diào)用 bindService()綁定到服務。Android 系統(tǒng)隨后調(diào)用服務的 onBind()方法背稼,該方法返回用于與服務交互的 IBinder贰军。
綁定是異步的。bindService()會立即返回蟹肘,“不會”使 IBinder 返回客戶端词疼。要接收 IBinder,客戶端必須創(chuàng)建一個 ServiceConnection實例帘腹,并將其傳遞給 bindService()寒跳。ServiceConnection包括一個回調(diào)方法,系統(tǒng)通過調(diào)用它來傳遞 IBinder竹椒。

:只有 Activity童太、服務和內(nèi)容提供程序可以綁定到服務 — 您無法從廣播接收器綁定到服務。

因此,要想從您的客戶端綁定到服務书释,您必須:
1.實現(xiàn) ServiceConnection翘贮。
您的實現(xiàn)必須重寫兩個回調(diào)方法:

  • onServiceConnected()
    系統(tǒng)會調(diào)用該方法以傳遞服務的onBind()方法返回的 IBinder。
  • onServiceDisconnected()
    Android 系統(tǒng)會在與服務的連接意外中斷時(例如當服務崩潰或被終止時)調(diào)用該方法爆惧。當客戶端取消綁定時狸页,系統(tǒng)“不會”**調(diào)用該方法。

2.調(diào)用 [bindService()扯再,傳遞 ServiceConnection 實現(xiàn)芍耘。
3.當系統(tǒng)調(diào)用您的 onServiceConnected() 回調(diào)方法時,您可以使用接口定義的方法開始調(diào)用服務熄阻。
4.要斷開與服務的連接斋竞,請調(diào)用 unbindService()。
如果應用在客戶端仍綁定到服務時銷毀客戶端秃殉,則銷毀會導致客戶端取消綁定坝初。 更好的做法是在客戶端與服務交互完成后立即取消綁定客戶端。 這樣可以關閉空閑服務钾军。

例如鳄袍,以下代碼段通過擴展 Binder 類將客戶端與上面創(chuàng)建的服務相連,因此它只需將返回的 IBinder轉(zhuǎn)換為 LocalService類并請求 LocalService實例:

LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
    // Called when the connection with the service is established
    public void onServiceConnected(ComponentName
 className, IBinder service) {
        // Because we have bound to an explicit
        // service that is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }
    // Called when the connection with the service disconnects unexpectedly
    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "onServiceDisconnected");
        mBound = false;
    }
};

客戶端可通過將此 ServiceConnection傳遞至 bindService()綁定到服務吏恭。例如:

Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

bindService()的第一個參數(shù)是一個 Intent拗小,用于顯式命名要綁定的服務(但 Intent 可能是隱式的)
第二個參數(shù)是 ServiceConnection對象
第三個參數(shù)是一個指示綁定選項的標志。它通常應該是 BIND_AUTO_CREATE樱哼,以便創(chuàng)建尚未激活的服務十籍。其他可能的值為 BIND_DEBUG_UNBIND 和 BIND_NOT_FOREGROUND,或 0(表示無)唇礁。

附加說明
以下是一些有關綁定到服務的重要說明:

  • 您應該始終捕獲 DeadObjectException異常,它們是在連接中斷時引發(fā)的惨篱。這是遠程方法引發(fā)的唯一異常盏筐。
  • 對象是跨進程計數(shù)的引用。
    您通常應該在客戶端生命周期的匹配引入 (bring-up) 和退出 (tear-down) 時刻期間配對綁定和取消綁定砸讳。 例如:如果您只需要在 Activity 可見時與服務交互琢融,則應在 onStart() 期間綁定,在 onStop()期間取消綁定簿寂。
  • 如果您希望 Activity 在后臺停止運行狀態(tài)下仍可接收響應漾抬,則可在 onCreate() 期間綁定,在 onDestroy()期間取消綁定常遂。請注意纳令,這意味著您的 Activity 在其整個運行過程中(甚至包括后臺運行期間)都需要使用服務,因此如果服務位于其他進程內(nèi),那么當您提高該進程的權重時平绩,系統(tǒng)終止該進程的可能性會增加圈匆。

:通常情況下,切勿在 Activity 的 onResume()和 onPause() 期間綁定和取消綁定捏雌,因為每一次生命周期轉(zhuǎn)換都會發(fā)生這些回調(diào)跃赚,您應該使發(fā)生在這些轉(zhuǎn)換期間的處理保持在最低水平。此外性湿,如果您的應用內(nèi)的多個 Activity 綁定到同一服務纬傲,并且其中兩個 Activity 之間發(fā)生了轉(zhuǎn)換,則如果當前 Activity 在下一個 Activity 綁定(恢復期間)之前取消綁定(暫停期間)肤频,系統(tǒng)可能會銷毀服務并重建服務叹括。 (Activity文檔中介紹了這種有關 Activity 如何協(xié)調(diào)其生命周期的 Activity 轉(zhuǎn)換。)

如需查看更多顯示如何綁定到服務的示例代碼着裹,請參閱 ApiDemos 中的 RemoteService.java
類领猾。
管理綁定服務的生命周期
當服務與所有客戶端之間的綁定全部取消時,Android 系統(tǒng)便會銷毀服務(除非還使用 onStartCommand()啟動了該服務)骇扇。因此摔竿,如果您的服務是純粹的綁定服務,則無需對其生命周期進行管理 — Android 系統(tǒng)會根據(jù)它是否綁定到任何客戶端代您管理少孝。
不過继低,如果您選擇實現(xiàn) onStartCommand() 回調(diào)方法,則您必須顯式停止服務稍走,因為系統(tǒng)現(xiàn)在已將服務視為已啟動袁翁。在此情況下,服務將一直運行到其通過 stopSelf()自行停止婿脸,或其他組件調(diào)用 stopService() 為止粱胜,無論其是否綁定到任何客戶端。
此外狐树,如果您的服務已啟動并接受綁定焙压,則當系統(tǒng)調(diào)用您的 onUnbind()方法時,如果您想在客戶端下一次綁定到服務時接收 onRebind()調(diào)用抑钟,則可選擇返回 true涯曲。onRebind()返回空值,但客戶端仍在其 onServiceConnected()回調(diào)中接收 IBinder在塔。下文圖 1 說明了這種生命周期的邏輯幻件。

圖 1. 允許綁定的已啟動服務的生命周期。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛔溃,一起剝皮案震驚了整個濱河市绰沥,隨后出現(xiàn)的幾起案子篱蝇,更是在濱河造成了極大的恐慌,老刑警劉巖揪利,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件态兴,死亡現(xiàn)場離奇詭異,居然都是意外死亡疟位,警方通過查閱死者的電腦和手機瞻润,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甜刻,“玉大人绍撞,你說我怎么就攤上這事〉迷海” “怎么了傻铣?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長祥绞。 經(jīng)常有香客問我非洲,道長,這世上最難降的妖魔是什么蜕径? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任两踏,我火速辦了婚禮,結果婚禮上兜喻,老公的妹妹穿的比我還像新娘梦染。我一直安慰自己,他們只是感情好朴皆,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布帕识。 她就那樣靜靜地躺著,像睡著了一般遂铡。 火紅的嫁衣襯著肌膚如雪肮疗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天扒接,我揣著相機與錄音伪货,去河邊找鬼。 笑死珠增,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的砍艾。 我是一名探鬼主播蒂教,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼脆荷!你這毒婦竟也來了凝垛?” 一聲冷哼從身側響起懊悯,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梦皮,沒想到半個月后炭分,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡剑肯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年捧毛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片让网。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡呀忧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出溃睹,到底是詐尸還是另有隱情而账,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布因篇,位于F島的核電站泞辐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏竞滓。R本人自食惡果不足惜咐吼,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虽界。 院中可真熱鬧汽烦,春花似錦、人聲如沸莉御。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽礁叔。三九已至牍颈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間琅关,已是汗流浹背煮岁。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涣易,地道東北人画机。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像新症,于是被迫代替她去往敵國和親步氏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

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

  • 綁定服務: 綁定服務是客戶端-服務器接口中的服務器徒爹。綁定服務可讓組件(例如 Activity)綁定到服務荚醒、發(fā)送請求...
    pifoo閱讀 1,222評論 0 4
  • [文章內(nèi)容來自Developers] AIDL(Android 接口定義語言)與您可能使用過的其他 IDL 類似芋类。...
    岳小川閱讀 424評論 0 3
  • 目錄0x10 介紹0x20 知識準備0x30 創(chuàng)建綁定服務0x31 擴展 Binder 類0x32 使用 Mess...
    zhangweiheb閱讀 2,283評論 0 0
  • 多少日月 多少浮沉 只愿一聲晚安 愿夜的靜謐 愿心的安詳 一天的好壞 從心放下 心無掛礙 明日的燦爛 睜眼即見 唯...
    雨與城閱讀 158評論 1 2
  • 總在相思時,恰逢別離間界阁,此情無計可消除侯繁。夜不能寐時,千里寄相思泡躯。待到草長鶯飛時贮竟,牽玉手,攬蠻腰精续,重拾舊溫存坝锰。待來年...
    藍山居士閱讀 473評論 0 51