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
- package com.ds.server;
- 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;
- import android.widget.Toast;
- public class AidlServerActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Button bt = (Button) findViewById(R.id.bt);
- bt.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Intent service = new Intent(AidlServerActivity.this,
- AidlService.class);
- startService(service);
- Toast.makeText(AidlServerActivity.this, "service started",
- Toast.LENGTH_LONG).show();
- }
- });
- }
- }
- package com.ds.server;
- interface IAidlService {
- int getType();
- }
AidlService.java
- package com.ds.server;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- public class AidlService extends Service {
- private boolean unrunnable;
- private int count;
- private class MyBinder extends IAidlService.Stub {
- @Override
- public int getType() throws RemoteException {
- // TODO Auto-generated method stub
- return 100;
- }
- }
- private void Log(String str) {
- Log.d("AidlService", "------ " + str + "------");
- }
- @Override
- public void onCreate() {
- super.onCreate();
- /*
- new Thread(new Runnable(){
- @Override
- public void run(){
- while(!unrunnable){
- try{
- Thread.sleep(1000);
- }catch(InterruptedException e){
- }
- count++;
- Log.v("AidlService","count:"+count);
- }
- }
- }).start();
- */
- Log.v("RemoteCountService","onCreate");
- Log("service create");
- }
- /*
- @Override
- public void onStart(Intent intent, int startId) {
- 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;"> }
- */
- @Override
- public IBinder onBind(Intent t) {
- Log("service on bind");
- return new MyBinder();
- }
- @Override
- public void onDestroy() {
- Log("service on destroy");
- unrunnable=true;
- super.onDestroy();
- }
- /*
- @Override
- public boolean onUnbind(Intent intent) {
- Log("service on unbind");
- return super.onUnbind(intent);
- }
- public void onRebind(Intent intent) {
- Log("service on rebind");
- super.onRebind(intent);
- }
- */
- }
布局文件AndroidManifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="https://schemas.android.com/apk/res/android"
- package="com.ds.server"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="8" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".AidlServerActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service
- android:name=".AidlService"
- android:enabled="true"
- android:process=":remote" >
- <intent-filter>
- <!-- AIDL完整路徑名。必須指明,客戶端能夠通過AIDL類名查找到它的實現類 -->
- <action android:name="com.ds.server.IAidlService" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </service>
- </application>
- </manifest>
這裏,服務器端的工作做好了,接下來是客戶端的工作。
2.接著,是客戶端的:
1)首先,創建一個工程
2)接著,把服務器端的一些文件拷貝過來(創建com.ds.server這個包,然後往裏麵複製進入如下圖的服務器端的文件(IAidlService.java)
下麵是個文件的內容
AidlClientActivity.java
- package com.ds.client;
- import com.ds.server.IAidlService;
- import android.app.Activity;
- 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.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class AidlClientActivity extends Activity {
- IAidlService iservice;
- int count;
- private ServiceConnection connection = new ServiceConnection() {
- public void onServiceConnected(ComponentName name, IBinder service) {
- // TODO Auto-generated method stub
- // 浠庤繙紼媠ervice涓幏寰桝IDL瀹炰緥鍖栧璞�
- iservice = IAidlService.Stub.asInterface(service);
- Log.i("Client","Bind Success:" + iservice);
- }
- public void onServiceDisconnected(ComponentName name) {
- // TODO Auto-generated method stub
- iservice = null;
- Log.i("Client","onServiceDisconnected");
- }
- };
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final TextView tv = (TextView) findViewById(R.id.tv);
- Button bt = (Button) findViewById(R.id.bt);
- bt.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- // TODO Auto-generated method stub
- Intent service = new Intent(IAidlService.class.getName());
- bindService(service, connection, BIND_AUTO_CREATE);
- if (iservice != null) {
- try {
- Log.v("AidlClientActivity","oncreate"+iservice.getType()+" "+count);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- else{
- count++;
- }
- }
- });
- }
- }
AndroidManifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="https://schemas.android.com/apk/res/android"
- package="com.ds.client"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="8" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".AidlClientActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </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
上一篇:
看Ubuntu如何提升Linux級別
下一篇:
Win 8狂想 走自己的路讓別的係統無路可走?
SQL Update 語句中使用別名
一張圖看懂你與AI的優劣勢
When does the Oracle library for st_shapelib.dll need to be changed?
Eclipse中編譯Android項目工程失敗,提示: Error in an XML file: aborting build 解決辦法
阿裏雲啟動天池電力AI大賽:用AI解千萬企業“用電之痛”
雲棲大會新零售峰會7位頂級大咖演講幹貨+完整版PPT全分享
mysql批量刪除指定前綴的表,批量修改表名的SQL語句
論網站建設的價值體現
Linux下調試段錯誤的方法[Segmentation Fault]--GDB
Eclipse快捷鍵大全