Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android服務(Service)研究

Android服務(Service)研究

編輯:關於Android編程

Service是android四大組件之一,沒有用戶界面,一直在後台運行。   為什麼使用Service啟動新線程執行耗時任務,而不直接在Activity中啟動一個子線程處理?   1、Activity會被用戶退出,Activity所在的進程就變成了空進程(沒有任何活動組件的進程),系統需要內存可能會優先終止該進程;   2、如果宿主進程被終止,那麼該進程內所有的子線程也會被終止,這樣可能導致子線程無法執行完成;   3、其實兩種方式都是可以處理耗時任務的,使用場景不同而已。   一、通過Start方式啟動Service   這種方式啟動的Sevice,訪問者與service之間沒有關聯,即使訪問者退出Service仍然執行   生命周期:onCreate()->onStartCommand()->onDestroy()   》定義一個繼承Service的子類    
public class NormalService extends Service {

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "啟動成功", Toast.LENGTH_SHORT).show();
        Log.d("NormalService", "啟動成功");
        //一般在這裡啟動新線程執行耗時的操作
        return super.onStartCommand(intent, flags, startId);
    }
}

 

    》在AndroidManifest.xml文件中配置該Service   <service android:name="com.android.servicetest.service.NormalService" /> 》在activity中使用   private void startNormal() {     nomalIntent = new Intent();     nomalIntent.setClass(this, NormalService.class);     startService(nomalIntent); } 二、通過bind方式啟動Service   這種方式啟動的Sercice,訪問者與Service綁定在一起,訪問者退出,Service也就終止了   生命周期:onCreate()->onBind()->onUnbind()->onDestroy()   》定義一個繼承Service的子類    
public class BinderService extends Service {

    private int count;
    private MyBinder mBinder;

    @Override
    public IBinder onBind(Intent arg0) {
        if (mBinder == null) {
            mBinder = new MyBinder();
        }
        Toast.makeText(this, "綁定成功", Toast.LENGTH_SHORT).show();
        Log.d("BinderService", "綁定成功");
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        new Thread(new Runnable() {

            @Override
            public void run() {
            while (true) {
                try {
                Thread.sleep(1000);
                count++;
                } catch (Exception e) {

                }
            }
            }
        }).start();
    }

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

 

》在AndroidManifest.xml文件中配置該Service   <service android:name="com.android.servicetest.service.BinderService" /> 》在activity中使用    
private MyBinder mBinder;
    
private ServiceConnection conn = new ServiceConnection() {

    @Override
    public void onServiceDisconnected(ComponentName arg0) {

    }

    @Override
    public void onServiceConnected(ComponentName arg0, IBinder binder) {
    mBinder = (BinderService.MyBinder) binder;
    }
};

private void bindService() {
    bindIntent = new Intent();
    bindIntent.setClass(this, BinderService.class);
    bindService(bindIntent, conn, Service.BIND_AUTO_CREATE);
}
 

 

  @Override protected void onDestroy() {     super.onDestroy();     unbindService(conn); } Binder對象相當於Service組件的內部鉤子,關聯到綁定的Service組件;   當其他的程序組件綁定該Service時,Service會把Binder對象返回給其他程序組件,其他程序組件通過該Binder對象即可與Service組件進行實時通信。   三、IntentService,處理異步請求的服務   IntentService是Service的子類,它增加了額外的功能:   使用隊列來管理請求Intent,每當客戶端代碼通過Intent請求啟動IntentService時,IntentService會將該Intent加入隊列中,然後開啟一條新的worker線程處理隊列中的Intent,因此不會阻塞主線程。   IntentService會按次序處理隊列中的Intent,該線程保證同一時刻只處理一個Intent。   》IntentService的實現    
public class IntentServiceTest extends IntentService{

    public IntentServiceTest() {
        super("IntentService");
    }

    @Override
    protected void onHandleIntent(Intent arg0) {
        Toast.makeText(this, "啟動成功", Toast.LENGTH_SHORT).show();
        Log.d("IntentServiceTest", "啟動成功");
        //該方法可以執行耗時的操作
        long endTime = System.currentTimeMillis() + 20 * 1000;
        while(System.currentTimeMillis() < endTime){
            synchronized (this) {
            try{
                wait(endTime - System.currentTimeMillis());
            }catch(Exception e){
                
            }
            }
        }
    }
}

 

    》在AndroidManifest.xml文件中配置該Service   <service android:name="com.android.servicetest.service.IntentServiceTest" /> 》在activity中使用   private void startIntentService(){     serviceIntent = new Intent();     serviceIntent.setClass(this, IntentServiceTest.class);     startService(serviceIntent); } 四、跨進程調用Service(AIDL Service)   Android各應用程序都運行在自己的進程中,進程之間無法直接進行數據交換,為了事項這種跨進程通信,Android提供了AIDL Service。   》創建AIDL文件,定義接口的源代碼必須以.aidl結尾   package com.android.servicetest.service;   interface IMusic{     String getName();     String getYear(); } 定義好AIDL接口之後,ADT工具會自動在gen/com/android/servicetest/service/目錄生成一個IMusic接口;   在該接口裡包含一個Stub內部類,該內部類除了實現IMusic接口還實現了IBinder接口,這個Stub類將會作為遠程Service的回調類。   》定義一個Service實現類    
public class MusicService extends Service{

    private MusicBinder mBinder;
    
    @Override
    public IBinder onBind(Intent arg0) {
        if(mBinder == null){
            mBinder = new MusicBinder();
        }
        Toast.makeText(this, "綁定成功", Toast.LENGTH_SHORT).show();
        Log.d("MusicService", "綁定成功");
        return mBinder;
    }

    public class MusicBinder extends IMusic.Stub{

        @Override
        public String getName() throws RemoteException {
            return "本草綱目";
        }

        @Override
        public String getYear() throws RemoteException {
            return "2006";
        }
        
    }
} 

 

  》在AndroidManifest.xml文件中配置該Service   <service android:name="com.android.servicetest.service.MusicService" /> 》在activity中使用    
private IMusic musicService;

private ServiceConnection = new ServiceConnection() {
        
    @Override
    public void onServiceDisconnected(ComponentName arg0) {
    
    }
    
    @Override
    public void onServiceConnected(ComponentName arg0, IBinder binder) {
        //獲取遠程Service的OnBind方法返回的對象的代理
        musicService = IMusic.Stub.asInterface(binder);
    }
};

private void bindAidlService(){
    aidlIntent = new Intent();
    aidlIntent.setClass(this, MusicService.class);
    bindService(aidlIntent, connAidl, Service.BIND_AUTO_CREATE);
}

private void showContent() {
    String content = "";
    try {
        content = musicService.getYear() + musicService.getName();
    } catch (Exception e) {
    }
    Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
}

 

    @Override protected void onDestroy() {     super.onDestroy();     unbindService(connAidl); } 這種方式和綁定本地Service的差別很小,只是獲取Service回調的方式有區別:   綁定本地Service時可以直接獲取OnBind方法的返回值;綁定遠程Service時獲取的事OnBind方法返回的對象的代理。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved