閱讀570 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android學習之遠程綁定調用service

https://res.3425.com.cn/aliyunqi/v4ezoht0a4y

遠程綁定調用service主要是用來不同進程的信息共享。就比如服務器和客戶端,在服務器端設置好一個service提供方法或信息,然後客戶端可以直接調用服務器端service提供方法或信息。這裏有個前提是客戶端必須有和服務器端一份一樣的AIDL,然後服務器端在客戶端使用的係統上有注冊過(也就是安裝運行過一次),之後客戶端就可以遠程綁定調用服務器端的service了。


具體的步驟如下:

1.首先,是服務器的

  1)創建一個android應用工程  

   

  2)  在主Aitivity所在的包裏新建個AIDL文件,這是ADT會自動幫你在gen目錄下生成一個和AIDL文件同名的JAVA文件(這裏的AidlService.java是下一步驟生成的,這裏可以先忽略)

  

  3)如上圖所示,創建一個用來使用service的類(AidlService.java)

  具體每個文件的代碼如下:

  AidlServerActivity.java

 

[java] view plaincopy
  1. package com.ds.server;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.Toast;  
  10.   
  11. public class AidlServerActivity extends Activity {  
  12.     /** Called when the activity is first created. */  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.         Button bt = (Button) findViewById(R.id.bt);  
  18.         bt.setOnClickListener(new OnClickListener() {  
  19.   
  20.             @Override  
  21.             public void onClick(View v) {  
  22.                 // TODO Auto-generated method stub  
  23.                 Intent service = new Intent(AidlServerActivity.this,  
  24.                         AidlService.class);  
  25.                 startService(service);  
  26.                 Toast.makeText(AidlServerActivity.this"service started",  
  27.                         Toast.LENGTH_LONG).show();  
  28.             }     
  29.   
  30.         });    
  31.   
  32.     }  
  33. }  



IAidlService.aidl

[java] view plaincopy
  1. package com.ds.server;  
  2. interface IAidlService {    
  3.     int getType();   
  4. }    

 AidlService.java

[java] view plaincopy
  1. package com.ds.server;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.IBinder;  
  6. import android.os.RemoteException;  
  7. import android.util.Log;  
  8.   
  9. public class AidlService extends Service {  
  10.     private boolean unrunnable;  
  11.     private int count;  
  12.   
  13.     private class MyBinder extends IAidlService.Stub {  
  14.   
  15.         @Override  
  16.         public int getType() throws RemoteException {  
  17.             // TODO Auto-generated method stub  
  18.             return 100;  
  19.         }  
  20.     }  
  21.     private void Log(String str) {   
  22.         Log.d("AidlService""------ " + str + "------");  
  23.     }  
  24.   
  25.     @Override  
  26.     public void onCreate() {  
  27.         super.onCreate();  
  28.         /* 
  29.         new Thread(new Runnable(){ 
  30.             @Override 
  31.             public void run(){ 
  32.                 while(!unrunnable){ 
  33.                     try{ 
  34.                         Thread.sleep(1000); 
  35.                     }catch(InterruptedException e){ 
  36.                     } 
  37.                     count++; 
  38.                     Log.v("AidlService","count:"+count); 
  39.                 }        
  40.             } 
  41.         }).start(); 
  42.         */  
  43.         Log.v("RemoteCountService","onCreate");  
  44.         Log("service create");  
  45.           
  46.     }  
  47. /* 
  48.     @Override 
  49.     public void onStart(Intent intent, int startId) { 
  50.         Log("service start border-style:none none none solid;border-left-width:3px;border-left-color:rgb(108,226,108);list-style:outside;color:inherit;line-height:18px;margin:0px;padding:0px 3px 0px 10px;">     } 
  51. */  
  52.     @Override  
  53.     public IBinder onBind(Intent t) {  
  54.         Log("service on bind");  
  55.         return new MyBinder();  
  56.     }  
  57.   
  58.     @Override  
  59.     public void onDestroy() {  
  60.         Log("service on destroy");  
  61.         unrunnable=true;  
  62.         super.onDestroy();  
  63.     }  
  64.     /* 
  65.  
  66.     @Override 
  67.     public boolean onUnbind(Intent intent) { 
  68.         Log("service on unbind"); 
  69.         return super.onUnbind(intent); 
  70.     } 
  71.  
  72.     public void onRebind(Intent intent) { 
  73.         Log("service on rebind"); 
  74.         super.onRebind(intent); 
  75.     } 
  76.     */  
  77.   
  78. }  

布局文件AndroidManifest.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="https://schemas.android.com/apk/res/android"  
  3.     package="com.ds.server"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk android:minSdkVersion="8" />  
  8.   
  9.     <application  
  10.         android:icon="@drawable/ic_launcher"  
  11.         android:label="@string/app_name" >  
  12.         <activity  
  13.             android:name=".AidlServerActivity"  
  14.             android:label="@string/app_name" >  
  15.             <intent-filter>  
  16.                 <action android:name="android.intent.action.MAIN" />  
  17.   
  18.                 <category android:name="android.intent.category.LAUNCHER" />  
  19.             </intent-filter>  
  20.         </activity>  
  21.   
  22.         <service  
  23.             android:name=".AidlService"  
  24.             android:enabled="true"  
  25.             android:process=":remote" >  
  26.             <intent-filter>  
  27.   
  28.                 <!-- AIDL完整路徑名。必須指明,客戶端能夠通過AIDL類名查找到它的實現類 -->  
  29.                 <action android:name="com.ds.server.IAidlService" />  
  30.                 <category android:name="android.intent.category.DEFAULT" />  
  31.             </intent-filter>  
  32.         </service>  
  33.     </application>  
  34.   
  35. </manifest>  


這裏,服務器端的工作做好了,接下來是客戶端的工作。


2.接著,是客戶端的:

 1)首先,創建一個工程

 

 2)接著,把服務器端的一些文件拷貝過來(創建com.ds.server這個包,然後往裏麵複製進入如下圖的服務器端的文件(IAidlService.java)

 

下麵是個文件的內容

    AidlClientActivity.java

   

[java] view plaincopy
  1. package com.ds.client;  
  2.   
  3. import com.ds.server.IAidlService;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.ComponentName;  
  7. import android.content.Intent;  
  8. import android.content.ServiceConnection;  
  9. import android.os.Bundle;  
  10. import android.os.IBinder;  
  11. import android.os.RemoteException;  
  12. import android.util.Log;  
  13. import android.view.View;  
  14. import android.view.View.OnClickListener;  
  15. import android.widget.Button;  
  16. import android.widget.TextView;  
  17.   
  18. public class AidlClientActivity extends Activity {  
  19.   
  20.     IAidlService iservice;   
  21.     int count;  
  22.   
  23.     private ServiceConnection connection = new ServiceConnection() {  
  24.   
  25.         public void onServiceConnected(ComponentName name, IBinder service) {  
  26.             // TODO Auto-generated method stub  
  27.             // 浠庤繙紼媠ervice涓幏寰桝IDL瀹炰緥鍖栧璞�            
  28.             iservice = IAidlService.Stub.asInterface(service);  
  29.             Log.i("Client","Bind Success:" + iservice);  
  30.         }    
  31.   
  32.         public void onServiceDisconnected(ComponentName name) {  
  33.             // TODO Auto-generated method stub  
  34.             iservice = null;  
  35.             Log.i("Client","onServiceDisconnected");  
  36.         }  
  37.     };    
  38.     
  39.     /** Called when the activity is first created. */  
  40.     @Override  
  41.     public void onCreate(Bundle savedInstanceState) {    
  42.         super.onCreate(savedInstanceState);  
  43.         setContentView(R.layout.main);  
  44.         final TextView tv = (TextView) findViewById(R.id.tv);  
  45.         Button bt = (Button) findViewById(R.id.bt);  
  46.         bt.setOnClickListener(new OnClickListener() {  
  47.               
  48.   
  49.             @Override  
  50.             public void onClick(View arg0) {  
  51.                 // TODO Auto-generated method stub  
  52.                 Intent service = new Intent(IAidlService.class.getName());  
  53.                 bindService(service, connection, BIND_AUTO_CREATE);  
  54.                 if (iservice != null) {    
  55.                     try {  
  56.                         Log.v("AidlClientActivity","oncreate"+iservice.getType()+" "+count);  
  57.                     } catch (RemoteException e) {  
  58.                         e.printStackTrace();  
  59.                     }  
  60.                 }  
  61.                 else{  
  62.                     count++;  
  63.                 }  
  64.             }  
  65.   
  66.         });  
  67.   
  68.     }  
  69. }  


 AndroidManifest.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="https://schemas.android.com/apk/res/android"  
  3.     package="com.ds.client"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk android:minSdkVersion="8" />  
  8.   
  9.     <application  
  10.         android:icon="@drawable/ic_launcher"  
  11.         android:label="@string/app_name" >  
  12.         <activity  
  13.             android:name=".AidlClientActivity"  
  14.             android:label="@string/app_name" >  
  15.             <intent-filter>  
  16.                 <action android:name="android.intent.action.MAIN" />  
  17.   
  18.                 <category android:name="android.intent.category.LAUNCHER" />  
  19.             </intent-filter>  
  20.         </activity>  
  21.     </application>  
  22.   
  23. </manifest>  
這樣客戶端的工作也算完了,但這裏我還想說下一個問題。

你可能會看到在客戶端的Activity文件裏,有個count的變量,覺得是多餘的,但這是為了說明下麵這個問題的需要。

最開始的count是0,然後我運行客戶端後,鼠標左擊bind按鈕,會發現LogCat的verbose窗口會顯示


為什麼沒有執行 Log.v("AidlClientActivity","oncreate"+iservice.getType()+" "+count);這一句,然後我再點擊下bind


終於出現想要的結果,這裏你就會發現count變成1了,也就是之前執行過一次count+1了,這就說明了,第一次隻是綁定,返回的 iservice是null,第二次以上才會返回對象。

到這裏就是我之前一直錯誤的地方,是理解錯了,我之前寫的程序沒有按鈕,是直接啟動客戶端後就綁定調用service,由於沒有按鈕不能多次按,也就會造成得不到想要的結果了。這裏總算明白它的一些運行機製了,先寫到這裏,後麵有什麼新發現會及時更新。


最後更新:2017-04-04 07:03:34

  上一篇:go 看Ubuntu如何提升Linux級別
  下一篇:go Win 8狂想 走自己的路讓別的係統無路可走?