Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android學習筆記五之Service

Android學習筆記五之Service

編輯:關於Android編程

1、什麼是Service?

  什麼是Service?Service是Android系統的四大組件之一,官方文檔是這樣描述Service的:

A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

  翻譯過來就是:服務是一個應用程序組件,可以在後台執行長時間運行的操作,不提供用戶界面。另一個應用程序組件可以啟動一個服務,它將繼續在後台運行,即使用戶切換到另一個應用程序。此外,一個組件可以綁定到一個服務的互動,甚至執行進程間通信(IPC)。例如,一個服務可以處理網絡交互、播放音樂、執行文件I/O、或與內容提供者進行交互,都來自後台。

2、Service的分類

按運行地點分:

本地服務(LocalService):本地服務依附在主線程上而不是一個獨立的進程,這樣節約了內存資源,LocalService在同一進程中,不需要IPC和AIDL。但是LocalService當主進程被kill掉之後,服務也會停止。例如用於音樂播放等

遠程服務(RemoteService):RemoteService是一個獨立的進程,當Activity所在的進程被kill掉之後,還會存在,可以為多個進程服務,不受進程影響。對應進程名格式為所在包名加上你指定的android:process字符串。一般是系統提供的服務,這種服務會常駐內存,占用一定的資源。RemoteService一般非常少見,並且一般都是系統服務。

按運行類型分:

前台服務:在Notification顯示正在運行圖標,當服務被kill掉的時候,Notification顯示的圖標也會消失,對用戶有一定的通知作用,例如音樂播放服務。

後台服務:默認的服務就是後台服務,不會再通知欄顯示正在運行圖標,當服務被終止的時候,用戶看不到效果。某些不需要運行或者終止提示的服務,例如天氣更新等

後台服務創建運行圖標並且調用startForeground方法,才會使後台服務變成前台服務。

按使用方式分類:

startService 啟動的服務:主要用於啟動一個服務執行後台任務,不進行通信。停止服務使用stopService,啟動之後,關聯的Activity銷毀並不會影響Service。

bindService 啟動的服務:該方法啟動的服務要進行通信。停止服務使用unbindService。當綁定的Activity銷毀的時候,Service也會銷毀。

startService 同時也 bindService 啟動的服務:停止服務應同時使用stepService與unbindService

3、Service與Thread的區別

很多時候,我們都覺得用Thread比用Service簡單的多,但是為什麼還會使用Service呢?

Thread:Thread是比進程更小的單元,Thread 是程序執行的最小單元,它是分配CPU的基本單位。可以用 Thread 來執行一些異步的操作。一個進程裡面可以有多個Thread,Thread必須運行在進程裡面

Service:Service 是Android的一種機制,當它運行的時候如果是LocalService,那麼對應的 Service 是運行在主進程上的。如:onCreate,onStart 這些函數在被系統調用的時候都是在主進程上運行的。如果是RemoteService,那麼對應的 Service 則是運行在獨立進程上。

Thread是獨立於Activity運行的,當一個Activity啟動一個Thread的時候,只要Thread的run方法還沒有執行完或者不是在Activity中停止Thread,Thread會一直執行。這樣就會產生一個問題:當Thread還在運行,但是Activity被Finish掉了,其他的Activity不能持有當前Thread。

舉個例子:如果你的 Thread 需要不停地隔一段時間就要連接服務器做同步的話,該 Thread 需要在 Activity 沒有啟動的時候也在運行。這個時候當你啟動一個新Activity 就沒有辦法在該 Activity 裡面控制之前創建的Thread。因此你便需要創建並啟動一個 Service ,在 Service 裡面創建、運行並控制該 Thread,這樣便解決了該問題(因為任何 Activity 都可以控制同一 Service,而系統也只會創建一個對應 Service 的實例)。

可以把 Service 想象成一種消息服務,我們可以在任何有 Context 的地方調用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,來控制它,你也可以在 Service 裡注冊 BroadcastReceiver,在其他地方通過發送 broadcast 來控制它,當然這些都是 Thread 做不到的。所以我們需要Service。

4、Service的生命周期

與Activity一樣,Service也有一系列的生命周期方法,我們可以實現它們來監測service狀態的變化,並且在適當的時候執行適當的工作。如下圖就是Service的生命周期圖

\

  由上圖可以知道,Android使用Service有兩種方式,綁定啟動bindService和startService。還有一種就啟動後之後綁定Service。

Service生命周期方法詳解:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> public class ExampleService extends Service { int mStartMode; // indicates how to behave if the service is killed IBinder mBinder; // interface for clients that bind boolean mAllowRebind; // indicates whether onRebind should be used @Override public void onCreate() { // The service is being created } @Override public int onStartCommand(Intent intent, int flags, int startId) { // The service is starting, due to a call to startService() return mStartMode; } @Override public IBinder onBind(Intent intent) { // A client is binding to the service with bindService() return mBinder; } @Override public boolean onUnbind(Intent intent) { // All clients have unbound with unbindService() return mAllowRebind; } @Override public void onRebind(Intent intent) { // A client is binding to the service with bindService(), // after onUnbind() has already been called } @Override public void onDestroy() { // The service is no longer used and is being destroyed } }

onCreate()方法:當Service第一次被創建後立即回調該方法,該方法在Service整個生命周期中之調用一次

onStartCommand(Intent intent, int flags, int startId)方法:當客戶端調用startService(Intent)方法時會回調,可多次調用StartService方法, 但不會再創建新的Service實例,而是繼續復用前面產生的Service實例,但會繼續回調 onStartCommand()方法!

onBind(Intent intent)方法:此方法是Service都必須實現的方法,該方法會返回一個 IBinder對象,app通過該對象與Service組件進行通信!

onUnbind(Intent intent)方法:當該Service上綁定的所有客戶端都斷開時會回調該方法!

onDestroy()方法:當Service被銷毀的時候會回調該方法,該方法只會回調一次!

onRebind(Intent intent)方法:此方法在app調用onUnbind()方法之後需要重新綁定Service的時候調用。

StartService啟動Service

  第一次啟動會創建一個Service實例,依次調用onCreate()(onCreate方法只會調用一次)和onStartCommand()方法,此時Service 進入運行狀態,如果再次調用StartService啟動Service,將不會再創建新的Service對象, 系統會直接復用前面創建的Service對象,調用它的onStartCommand()方法!該Service將會一直在後台運行,而不管對應程序的Activity是否在運行,直到被調用stopService,或自身的stopSelf方法。當然如果系統資源不足,android系統也可能結束服務。

BindService啟動Service

  如果一個Service被某個Activity 調用 Context.bindService 方法綁定啟動,此後如果再次使用bindService綁定Service,系統不會創建新的Sevice實例,也不會再調用onBind()方法,只會直接把IBinder對象傳遞給其他後來增加的客戶端!不管調用 bindService 調用幾次,onCreate方法都只會調用一次,同時onStart方法始終不會被調用。當連接建立之後,Service將會一直運行,除非調用Context.unbindService 斷開連接或者之前調用bindService 的 Context 不存在了(如Activity被finish的時候),系統將會自動停止Service,對應onDestroy將被調用。

StartService啟動Service後bindService綁定

  如果一個Service又被啟動又被綁定,則該Service將會一直在後台運行。並且不管如何調用,onCreate始終只會調用一次,對應startService調用多少次,Service的onStart便會調用多少次。調用unbindService將不會停止Service,而必須調用 stopService 或 Service的 stopSelf 來停止服務。

特別注意
當調用bindService綁定Service的時候,必須要在某處調用unbindService解綁Service 當使用startService的時候,必須要使用stopService停止服務 當同時用startService和bindService時,要終止Service,必須要同時調用unbindService和stopService,不管 startService 與 bindService 的調用順序,如果先調用 unbindService 此時服務不會自動終止,再調用 stopService 之後服務才會停止,如果先調用 stopService 此時服務也不會終止,而再調用 unbindService 或者 之前調用 bindService 的 Context 不存在了(如Activity 被 finish 的時候)之後服務才會自動停止; 旋轉手機屏幕的時候,默認狀態下bindService會斷開 當想要使用Service的時候,必須要在AndroidManifest.xml中注冊。

5、IntentService

 由於Service和Activity一樣,都是運行在主線程中的,如果直接在Service裡面執行耗時操作會ANR,所以谷歌提供了一個IntentService來處理耗時操作。簡單來說,IntentService是繼承於Service並處理異步請求的一個類,在IntentService內有一個工作線程來處理耗時操作,啟動IntentService的方式和啟動傳統Service一樣,同時,當任務執行完後,IntentService會自動停止,而不需要我們去手動控制。另外,可以啟動IntentService多次,而每一個耗時操作會以worker queue的方式在IntentService的onHandleIntent回調方法中執行,並且,每次只會執行一個worker Thread,執行完第一個再執行第二個,以此類推。而且,所有請求都在一個單線程中,不會阻塞應用程序的主線程(UI Thread),同一時間只處理一個請求。

 IntentService在處理事務時,還是采用的Handler方式,創建一個名叫ServiceHandler的內部Handler,並把它直接綁定到HandlerThread所對應的子線程。 ServiceHandler把處理一個intent所對應的事務都封裝到叫做onHandleIntent的虛函數;因此我們直接實現虛函數onHandleIntent,再在裡面根據Intent的不同進行不同的事務處理就可以了。另外,IntentService默認實現了Onbind()方法,返回值為null。
  

 使用IntentService需要兩個步驟:

  1、寫構造函數

  2、實現虛函數onHandleIntent,並在裡面根據Intent的不同進行不同的事務處理。

 這樣做的好處是:處理異步請求的時候可以減少寫代碼的工作量,比較輕松地實現項目的需求

 注意:IntentService的構造函數一定是參數為空的構造函數,然後再在其中調用super(“name”)這種形式的構造函數。因為Service的實例化是系統來完成的,而且系統是用參數為空的構造函數來實例化Service的

public class MyIntentService extends IntentService {
final static String TAG="robin";
 public MyIntentService() {
  super("com.lenovo.robin.test.MyIntentService");
  Log.i(TAG,this+" is constructed");
 }
 @Override
 protected void onHandleIntent(Intent arg0) {
  Log.i(TAG,"begin onHandleIntent() in "+this);
  try {
   Thread.sleep(10*1000);
  } catch (InterruptedException e) {
 e.printStackTrace();
  }
  Log.i(TAG,"end onHandleIntent() in "+this);
 }
 public void onDestroy()
 {
  super.onDestroy();
  Log.i(TAG,this+" is destroy");
 }
}

IntentService源碼

package android.app;

import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;

public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        onHandleIntent((Intent)msg.obj);
        stopSelf(msg.arg1);
    }
}

public IntentService(String name) {
    super();
    mName = name;
}

public void setIntentRedelivery(boolean enabled) {
    mRedelivery = enabled;
}

@Override
public void onCreate() {
    // TODO: It would be nice to have an option to hold a partial wakelock
    // during processing, and to have a static startService(Context, Intent)
    // method that would launch the service & hand off a wakelock.

    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

@Override
public void onStart(Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

/**
 * You should not override this method for your IntentService. Instead,
 * override {@link #onHandleIntent}, which the system calls when the IntentService
 * receives a start request.
 * @see android.app.Service#onStartCommand
 */
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}

@Override
public void onDestroy() {
    mServiceLooper.quit();
}
@Override
public IBinder onBind(Intent intent) {
    return null;
}

   protected abstract void onHandleIntent(Intent intent);
}

5、Service實戰

通過startService啟動的Service:

   新建一個類繼承Service  

public class FirstService extends Service {

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

在清單文件中注冊Service


    
        
            

            
        
    
    

在Activity中調用startService方法

 btn_start_service = (Button) findViewById(R.id.btn_start_service);
    btn_start_service.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(), FirstService.class);
            startService(intent);
        }
    });

這樣,就完成了一個簡單的Service的創建和啟動,通過startService啟動的Service不會因為Activity的銷毀而銷毀,所以我們必須要調用stopService方法。

與Activity綁定的Service:

SecondService

public class SecondService extends Service {

private final String TAG = "SecondService";
private int count;
private boolean quit;


private MyBinder binder = new MyBinder();

public class MyBinder extends Binder {
    public int getCount() {
        return count;
    }
}


@Override
public IBinder onBind(Intent intent) {
    System.out.println("onBind方法被調用!");
    return binder;
}


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


@Override
public boolean onUnbind(Intent intent) {
    System.out.println("onUnbind方法被調用");
    return true;
}


@Override
public void onDestroy() {
    super.onDestroy();
    this.quit = true;
    System.out.println("onDestroy方法被調用");
}

@Override
public void onRebind(Intent intent) {
    System.out.println("onRebind方法被調用");
    super.onRebind(intent);
}
}

清單文件注冊


    
        
            

            
        
    
    
    

MainActivity

public class MainActivity extends AppCompatActivity {
Button btn_start_service;
Button btn_bind_service;

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

    btn_start_service = (Button) findViewById(R.id.btn_start_service);
    btn_start_service.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(), FirstService.class);
            startService(intent);
        }
    });


    btn_bind_service = (Button) findViewById(R.id.btn_bind_service);
    btn_bind_service.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(), SecondService.class);
            getApplicationContext().bindService(intent, mServiceConnection, Service.BIND_AUTO_CREATE);
        }
    });
}

ServiceConnection mServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        System.out.println("------->>service connected");
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        System.out.println("--------------->>service dis connected");
    }
};
}
IntentService

Service

public class ThridService extends IntentService {

public ThridService() {
    super("");
    System.out.println("intent Service");
}

@Override
protected void onHandleIntent(Intent intent) {
    String flag = intent.getExtras().getString("flag");
    if (flag.equals("t1")) {
        System.out.println("startServiceT1");
    } else if (flag.equals("t2")) {
        System.out.println("startServiceT2");
    }
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

清單文件


    
        
            

            
        
    

    
    
    


MainActivity

btn_intent_service = (Button) findViewById(R.id.btn_intent_service);
    btn_intent_service.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent it1 = new Intent(getApplicationContext(), ThridService.class);
            Bundle b1 = new Bundle();
            b1.putString("flag", "t1");
            it1.putExtras(b1);

            Intent it2 = new Intent(getApplicationContext(), ThridService.class);
            Bundle b2 = new Bundle();
            b2.putString("flag", "t2");
            it2.putExtras(b2);
            getApplicationContext().startService(it1);
            getApplicationContext().startService(it2);

        }
    });

這裡只是簡單的描述怎麼啟動一個Service,其他復雜的並沒有實現。

6、Binder機制

6.1、什麼是Binder?

  我們知道,AndroidOS是基於Linux內核的,但是AndroidOS沒有采用Linux內核提供的各種進程間通信機制(IPC),而是采用Binder機制。Android應用都是運行在獨立的進程中,這樣確保程序之間不會相互影響,但是,很多情況下,我們開發的程序中的Activity需要與系統Service進行通信,它們肯定不是在同一個進程,AndroidOS為我們提供了實現進程之間通信的方式,Binder就是其中的一種。

  AndroidOS中的Binder機制,是由client、Server、ServiceManager和Binder驅動程序,其中Client、Server和Service Manager運行在用戶空間,Binder驅動程序運行內核空間。下圖是這四個組件的關系:

\

 

6.1.1、Client端

客戶端要想訪問Binder的遠程服務,就必須獲取遠程服務的Binder對象在binder驅動層對應的mRemote引用。當獲取到mRemote對象的引用後,就可以調用相應Binder對象的服務了。

6.1.2、Service端

一個Binder服務器端就是一個Binder類的對象。當創建一個Binder對象後,內部就會開啟一個線程,這個線程用於接收binder驅動發送的信息,收到消息後,會執行相關的服務代碼。

6.1.3、ServiceManager

Service Manager是一個守護進程,用來管理Server,並向Client提供查詢Server接口的能力

6.1.4、Binder驅動

當服務端成功創建一個Binder對象後,Binder驅動也會相應創建一個mRemote對象,該對象的類型也是Binder類。客戶就可以借助這個mRemote對象來訪問遠程服務。

6.2、使用AIDL實現兩個進程的簡單通信

使用Android studio實現

在main下新建aidl文件夾,在aidl文件夾中新建和aidl包名相同的包,新建aidl file。
aidl

// IPerson.aidl
package com.example.devin.helloservice.aidl;

// Declare any non-default types here with import statements

interface IPerson {
  String findPersion(int num);
}

在build\generated\source\aidl下可以找到編譯生成的java代碼

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: H:\\AndroidStudioIDE\\workspace\\HelloService\\app\\src\\main\\aidl\\com\\example\\devin\\helloservice\\aidl\\IPerson.aidl
 */
package com.example.devin.helloservice.aidl;
// Declare any non-default types here with import statements

public interface IPerson extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.devin.helloservice.aidl.IPerson
{
private static final java.lang.String DESCRIPTOR = "com.example.devin.helloservice.aidl.IPerson";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.example.devin.helloservice.aidl.IPerson interface,
 * generating a proxy if needed.
 */
public static com.example.devin.helloservice.aidl.IPerson asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.devin.helloservice.aidl.IPerson))) {
return ((com.example.devin.helloservice.aidl.IPerson)iin);
}
return new com.example.devin.helloservice.aidl.IPerson.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_findPersion:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
java.lang.String _result = this.findPersion(_arg0);
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.devin.helloservice.aidl.IPerson
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public java.lang.String findPersion(int num) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(num);
mRemote.transact(Stub.TRANSACTION_findPersion, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_findPersion = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String findPersion(int num) throws android.os.RemoteException;
}

自定義一個Service類,繼承IPerson.Stub類 就是實現了IPerson接口和IBinder接口

package com.example.devin.helloservice.Service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;

import com.example.devin.helloservice.aidl.IPerson;

/**
 * Created by Devin on 2016/6/15.
 */
public class AIDLService extends Service {

private String[] names = {"張三", "李四", "王五", "趙六", "孫七"};
private IBinder mIBinder = new PersionBinder();

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return mIBinder;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    System.out.println("start service");
    return super.onStartCommand(intent, flags, startId);
}

private class PersionBinder extends IPerson.Stub {
    @Override
    public String findPersion(int num) throws RemoteException {
        if (num > 0 && num < 6) {
            return names[num - 1];
        }
        return "222";
    }
}
}

在清單文件中注冊


    
        
            

            
        
    
    

    
    
    
    

在客戶端中使用

package com.example.devin.helloservice;

import android.app.Service;
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.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.devin.helloservice.Service.AIDLService;
import com.example.devin.helloservice.aidl.IPerson;

/**
 * Created by Devin on 2016/6/15.
 */
public class SecondActivity extends AppCompatActivity implements View.OnClickListener {
EditText et_num;
Button btn_find;
TextView tv_name;
IPerson mIPerson;
PersionConnect mPersionConnect = new PersionConnect();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_aidl);

    et_num = (EditText) findViewById(R.id.et_num);
    btn_find = (Button) findViewById(R.id.btn_find);
    tv_name = (TextView) findViewById(R.id.tv_name);


    Intent intent = new Intent(this, AIDLService.class);
    startService(intent);
    this.bindService(intent, mPersionConnect, Service.BIND_AUTO_CREATE);

    btn_find.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    String etNum = et_num.getText().toString().trim();
    int num = Integer.valueOf(etNum);
    try {
        tv_name.setText(mIPerson.findPersion(num));
    } catch (RemoteException e) {
        e.printStackTrace();
    }
    et_num.setText("");
}

private class PersionConnect implements ServiceConnection {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mIPerson = IPerson.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mIPerson = null;
    }
}
}

這樣可以完成簡單的通信。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved