Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 初級開發 >> android service 使用以及aidl使用

android service 使用以及aidl使用

編輯:初級開發

service1:service的啟動方式
service 是一個在後台運行的服務。你所啟動的這個service所做得工作最好在另一個線程中做。因為這個service的線程的工作將阻塞調用它的線程。
創建和啟動一個service有兩種方式
Intent in = new Intent(***);
startService(in) 和 bindService(in)。
與上面相對應,停止一個service也有兩種方式
stopService(in)  和 unbindService(in)。 如果是本地的service 則 Intent in = new Intent(this,LocalService.class)。同時那個service要在manifest文件中標明自己的name
<service android:name = ".serviceA"/> 如果是非本地的service 則在Intent中指明就可以了Intent in= new Intent("com.test.A") 與此同時那個非本地的service也要在manifest文件中申明自己的name和intent-filter
    <service android:name = ".serviceA">
            <intent-filter>
               <action android:name="com.test.A"/>
               <category android:name="android.intent.category.DEFAULT" />
           </intent-filter>
        </service>2:使用startService 和 stopService
這種啟動和停止方式是比較簡單的。只需要在調用Activity中直接寫上就可以了。2.1service客戶端代碼
調用service的客戶端的activity的代碼:
package com.D_activity; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
public class D_activity extends Activity {
    Button b;
    private boolean running =  false;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);         b=(Button)findVIEwById(R.id.button);     @Override
    protected void onResume() {
//指定一個Intent
       final Intent in = new Intent("com.test.A");
        super.onResume();
        b.setOnClickListener(new OnClickListener(){             @Override
            public void onClick(VIEw v) {
                if(running){
                    running = false;                    stopService(in);
                    b.setText("start ");                 else{
                    running = true;                    startService(in);
                    b.setText("stop");             }         }); }
2.2 被startService()調用的service 的代碼:
通過startService啟動的service在service的生命周期中將調用:onCreate()->onStartCommand()->onDestory()。
onCreate 僅僅在第一次創建這個service的時候調用。onStartCommand會在你使用startService()後調用。onDestory會在你使用stopSerivce的時候調用。 以下代碼將實現一個每5秒打印系統時間的service,多半代碼都是從文檔中直接拿過來的。
package com.A_s; import Java.text.SimpleDateFormat; import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.os.Process;
import android.widget.Toast; public class serviceA extends Service {     private boolean flag =true;
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;     // Handler that receives messages from the thread
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);         @Override
        public void handleMessage(Message msg) {
            // Normally we would do some work here, like download a file.
            // For our sample, we just sleep for 5 seconds.
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            while(flag){
                synchronized (this) {
                      try {
                          Log.i("TEST","A  :"+sdf.format(System.currentTimeMillis()));
                          wait(5*1000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();                 }             // Stop the service using the startId, so that we don't stop
            // the service in the middle of handling another job
            stopSelf(msg.arg1);     }     @Override
    public void onCreate() {
      // Start up the thread running the service.  Note that we create a
      // separate thread because the service normally runs in the process's
      // main thread, which we don't want to block.  We also make it
      // background priority so CPU-intensive work will not disrupt our UI.
      HandlerThread thread = new HandlerThread("ServiceStartArguments",
              Process.THREAD_PRIORITY_BACKGROUND);
      thread.start();       // Get the HandlerThread's Looper and use it for our Handler
      mServiceLooper = thread.getLooper();
      mServiceHandler = new ServiceHandler(mServiceLooper);
    }     @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();         // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        mServiceHandler.sendMessage(msg);         // If we get killed, after returning from here, restart
        return START_STICKY;
    }     @Override
    public IBinder onBind(Intent intent) {
        // We don't provide binding, so return null
        return null;     
    @Override
    public void onDestroy() {
      Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
      flag =false; }
Manifest文件:
<service android:name = ".serviceA">
            <intent-filter>
               <action android:name="com.test.A"/>
               <category android:name="android.intent.category.DEFAULT" />
           </intent-filter>
        </service>3:使用bindService和 unbindService
這種方式啟動的service 生命周期中將調用:onCreate()->onBind()->onDestory()。
在service中與之前startService最不同的一點是,這次service不再使用onStartCommand而是使用onBind.所以這次service的代碼與上面service的不同僅僅在於把onStartCommand的邏輯代碼放到onBind中就可以了。
 @Override
    public IBinder onBind(Intent intent) {
        // We don't provide binding, so return null
        Toast.makeText(this, "service starting in onBind", Toast.LENGTH_SHORT).show();
        Message msg = mServiceHandler.obtainMessage();
        mServiceHandler.sendMessage(msg);         return IBind;
    }
3.1使用bindService的客戶端的代碼如下 這次的Activity明顯比之前使用startService的Activity多了一點東西,就是多了ServiceConnection類。當bindService完成時,系統會自動調用ServiceConnection中的onServiceConnected()
package com.C_activity; import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
import android.widget.Toast; public class C_activity extends Activity {
    Button b;
    private boolean running =  false;     @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentVIEw(R.layout.main);
        b=(Button)findVIEwById(R.id.button);     }
    @Override
    protected void onResume() {
       final Intent in = new Intent("com.test.E");
        super.onResume();
        b.setOnClickListener(new OnClickListener(){             @Override
            public void onClick(VIEw v) {
                if(running){
                    running = false;
                   unbindService(sc);
                    b.setText("start ");                 else{
                    running = true;
//bindService方法的最後一個參數有其特定的意義,最好找文檔確定自己需要哪種
                   bindService(in, sc, 1);
                    b.setText("stop");             }         });         private ServiceConnection sc = new ServiceConnection(){        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
           
        }        @Override
        public void onServiceDisconnected(ComponentName name) {    }4:利用aidl  遠程調用service
當service 不是本地的服務,也就不能通過onServiceConnected中的IBinder來強制轉換成相應服務類來使用service提供的一些方法。這時就需要使用aidl了。
直觀的去看,遠程服務如果能夠被操作,也需要提供一個操作的接口,而這個接口不光在服務器端實現,同時在客戶端也需要知道調用和使用的方式; 因此我們需要定義aidl文件來描述這麼一個服務,也就是通過雙方共享一個aidl文件的方式來共享一個接口。
在aidl裡面定義了這個接口的內容之後, android的IDE幫助編譯自動生成一個相應名字的java文件。這個Java裡面生成一個接口:test_aidl (extends android.os.IInterface) ,
 同時,最主要的,裡面有個樁: public static abstract class Stub extends android.os.Binder implements test_aidl 比如我寫了一個叫test_aidl.aidl的文件 內容如下:
package com.E_s;
 interface test_aidl{
    int getCount(); 那麼在工程的gen目錄下會自動生成一個test_aidl.Java文件。然後在service中你就可以使用並實現這個接口中的方法。  private final test_aidl.Stub IBind = new test_aidl.Stub() {       
        @Override
        public int getCount() throws RemoteException {
            // TODO Auto-generated method stub
            return i;     };4.1 使用aidl的service端的全部代碼如下:
package com.E_s; import Java.text.SimpleDateFormat; import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.os.Process;
import android.widget.Toast; public class serviceA extends Service {     private boolean flag =true;
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;
    public static int i = 0;     // Handler that receives messages from the thread
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);         @Override
        public void handleMessage(Message msg) {
            // Normally we would do some work here, like download a file.
            // For our sample, we just sleep for 5 seconds.
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            while(flag){
                synchronized (this) {
                      try {
                          i++;
                          Toast.makeText(serviceA.this, "E_s", Toast.LENGTH_SHORT).show();
                          Log.i("liyufei","E(A)  :"+sdf.format(System.currentTimeMillis()));
                          wait(5*1000);
                      } catch (InterruptedException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();                 }             // Stop the service using the startId, so that we don't stop
            // the service in the middle of handling another job
//            stopSelf(msg.arg1);     }     @Override
    public void onCreate() {
      // Start up the thread running the service.  Note that we create a
      // separate thread because the service normally runs in the process's
      // main thread, which we don't want to block.  We also make it
      // background priority so CPU-intensive work will not disrupt our UI.
      HandlerThread thread = new HandlerThread("ServiceStartArguments",
              Process.THREAD_PRIORITY_BACKGROUND);
      thread.start();       // Get the HandlerThread's Looper and use it for our Handler
      mServiceLooper = thread.getLooper();
      mServiceHandler = new ServiceHandler(mServiceLooper);
    }     @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(this, "service starting in onBind", Toast.LENGTH_SHORT).show();         Message msg = mServiceHandler.obtainMessage();
        mServiceHandler.sendMessage(msg);        return IBind;     
   private final test_aidl.Stub IBind = new test_aidl.Stub() {
        
        @Override
        public int getCount() throws RemoteException {
            return i;     @Override
    public void onDestroy() {
      Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
      flag =false; }
在客戶端,你首先要在客戶端的工程中也創建相應的包名和aidl文件。比如將文中的test_aidl.aidl也放入客戶端的com.E_s包中。然後客戶端中也會自動生成一個test_aidl.Java文件。
然後就只需要將之前的使用bindService的客戶端代碼中的ServiceConnection方法中添加些東西就好了。
    test_aidl testAidl;    private ServiceConnection sc = new ServiceConnection(){
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            testAidl = test_aidl.Stub.asInterface(service);         @Override
        public void onServiceDisconnected(ComponentName name) {
            testAidl = null;        }; 然後你就可以使用這個ta就可以直接操作service中的方法了。比如testAidl.getCount();
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved