Abdroid JAVA service

有時間,重新複習下,把以前做過的server 相關 整理下。當時可還是花了些時間查代碼的。

 

從最簡單的server 到支持回調的server。

 

1:最簡單的server,指只要應用的人來呼叫下,啓動他,沒別的交互的。

 

 

server端注意事項:

生成一個Service 的繼承類,默認重載onBind函數。(後面的代碼需要修改這個函數) 現在不用管他。

在AndroidManifest.xml裏面申明這個類

<service android:name=".TestServer" >
    <intent-filter>
                <action android:name="TestServer" />
                <category android:name="android.intent.category.DEFAULT" 
                />
            </intent-filter>
    </service>

 

 

client 端:

 Intent i = new Intent();
     i.setClassName( "com.test.testserver",
       "com.test.testserver.TestServer" );
    
    startService(i);

 

 

這樣一個簡單的引用就完成了。

 

注:這樣啓動的service是會一直存在的,不管客戶端的情況。除非你調用stopService(Intent)

另外,也可以用bindService(i, null, Context.BIND_AUTO_CREATE);來啓動service,這樣這個service是依附在client 上的,如果客戶端關掉,他也會關掉。bindService(i, null, Context.BIND_AUTO_CREATE);

 

 

 

2: 支持aidl的service,支持函數調用 (這樣不涉及到原理,相關android 原理我準備下一篇文章討論)

 

server端注意事項:

搞一個aidl文件,這個類似java的 interface

interface Itestserver {
 
 int testAdd(int i, int j);
 
     
}

 

這樣就會生成一個自動interface

public interface Itestserver extends android.os.IInterface

和一個類

public static abstract class Stub extends android.os.Binder implements com.arcsoft.testserver.Itestserver

 

這樣在代碼裏面生成新建立這樣一個對象,並實現定義的函數:

 

private final Itestserver.Stub mBinder = new Itestserver.Stub() {

  @Override
  public int testAdd(int i, int j) throws RemoteException {
   // TODO Auto-generated method stub
   return i+j;
  }
  };

 

修改OnBinder函數

 public IBinder onBind(Intent arg0) {
  // TODO Auto-generated method stub
  return mBinder;
 }

 

 

 

client 端:

把aidl 也copy過去,這樣也得到自動的Itestserver

 

實現一個ServiceConnection的子類。

 

class AdderServiceConnection implements ServiceConnection
    {
        public void onServiceConnected(ComponentName className,
   IBinder boundService )
        {
          service = Itestserver.Stub.asInterface((IBinder)boundService);
    //Log.d( "ADDERSERVICECLIENT","onServiceConnected" );
        
        }

        public void onServiceDisconnected(ComponentName className)
        {
          service = null;
   // Log.d( "ADDERSERVICECLIENT","onServiceDisconnected" );
        }
    };

 

調用binder方式來啓動service

 conn = new AdderServiceConnection();
    Intent i = new Intent();
    i.setClassName( "com.arcsoft.testserver",
         "com.arcsoft.testserver.TestServer" );
    bindService( i, conn, Context.BIND_AUTO_CREATE);

 

這樣就可以簡單的調用接口了:

 int t = service.testAdd(5,6);

 

 

3: 支持回調的service

如果涉及到類似UI刷新的問題,就必需支持回調。

要支持回調,有兩個需要注意的地方:

1:新定義一個回調AIDL,注意這個AIDL對應的stub要放在客戶端來實現,調用在service端。

2:使用RemoteCallbackList,來得的一個安全的調用。

 

服務器端:

 

新的AIDL

 

oneway interface ItestserverCallback {
   
    void processCompleted(int Retvalue);
}

 

修改前面的AIDL,增加註冊回調接口

interface Itestserver {
 
 int testAdd(int i, int j);
  void registerCallback(in ItestserverCallback cb);
  void unregisterCallback(in ItestserverCallback cb);
     
}

 

在代碼中增加新的對象:

 

final RemoteCallbackList<ItestserverCallback> mCallbacks = new RemoteCallbackList<ItestserverCallback>();

 

 

同時實現新的函數:

 @Override
  public void registerCallback(ItestserverCallback cb)
    throws RemoteException {
   // TODO Auto-generated method stub
   if (cb != null)
          mCallbacks.register(cb);
   
  }

  @Override
  public void unregisterCallback(ItestserverCallback cb)
    throws RemoteException {
   // TODO Auto-generated method stub
   if (cb != null)
          mCallbacks.unregister(cb);
   
  }

 

 

這樣就可以在server端使用這個回調了。

如在某個異步函數結束的時候調用以下函數

 

 void processend(final int res) {
      // Broadcast to all clients the new value.
      final int N = mCallbacks.beginBroadcast();
      for (int i = 0; i < N; i++) {
        try {
          mCallbacks.getBroadcastItem(i).processCompleted(res);
        } catch (RemoteException e) {
          // The RemoteCallbackList will take care of removing
          // the dead object for us.
        }
      }
      mCallbacks.finishBroadcast();

    }

 

 

 客戶端:

同樣引入新的AIDL

同時實現register的stub,並且註冊進去

 

private final ItestserverCallback.Stub mBinder = new ItestserverCallback.Stub() {

  @Override
  public void processCompleted(int Retvalue) throws RemoteException {
   // TODO Auto-generated method stub
   mHanler.sendMessage(mHanler.obtainMessage(1, Retvalue, 0));
  }

  
 
  }; 

 

try {
     service.registerCallback(mBinder);
    } catch (RemoteException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    

 

try {
   service.unregisterCallback(mBinder);
  } catch (RemoteException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 

這樣就可以通過管理handler,來處理事務了。

 

加一張流程圖,解釋整個RPC流程。

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章