1. 程式人生 > >android studio使用Aidl跨程序呼叫服務

android studio使用Aidl跨程序呼叫服務

以前就知道其大概程式碼流程,但是一直沒有敲程式碼去實現,今天將其實現了,android studio下編寫也遇到了一些小細節的問題,特此記錄一下。
既然是模擬Aidl通訊,那麼當然要編寫兩個應用了,一個提供服務給另一個應用呼叫,那麼開始吧。
一、服務提供方應用編寫
①.為了更全面一些,我編寫了一個自定義類Book在Aidl之中傳遞,不同程序間傳遞自定義物件必須實現Parcelable介面,Serializable是不行的哦。Book類如下:

package com.lbb.aidltest.bean;
import android.os.Parcel;
import android.os.Parcelable;
/**
 * 作者:李少波
 * 郵箱:
[email protected]
* 日期:16/10/20 */
public class Book implements Parcelable{ private String name; private int id; public Book(String name, int id) { this.name = name; this.id = id; } protected Book(Parcel in) { name = in.readString(); id = in.readInt(); } public
static final Creator<Book> CREATOR = new Creator<Book>() { @Override public Book createFromParcel(Parcel in) { return new Book(in); } @Override public Book[] newArray(int size) { return new Book[size]; } }; public
String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(name); parcel.writeInt(id); } }

②.編寫.Aidl檔案,因為此處用到了自定義類的物件的傳遞,所以需要編寫兩類aidl檔案,分別是定義服務介面的和定義自定義類的aidl檔案。
a.定義服務介面。右鍵-new-aidl-aidl file,檔名隨便定義,可以是服務的類名前邊加I。就像一個介面檔案一樣宣告對外開放的方法即可,此處需要注意的是:如果用到了自定義類,則需要顯示的import進來,此處需要顯示import com.lbb.aidltest.bean.Book,否則會”Execution failed for task :app:compileDebugAidl”。我的介面定義檔案如下:

// IAidlInterface.aidl
package com.lbb.aidltest;
import com.lbb.aidltest.bean.Book;
interface IAidlInterface {
 Book getBookByIndex(int index);
}

b.定義需要在程序間傳遞的自定義類同名的.aidl檔案,此處是Book.aidl。這一步不能右鍵建立aidl file了,因為輸入Book會提示”Interface Name must be unique”,導致無法下一步。所以只能在aidl資料夾下建立和Book一樣的包路徑,並在路徑下new-file,填入Book.aidl,手動輸入檔案內容如下(全程系統無任何提示輸入。。汗):

package com.lbb.aidltest.bean;
parcelable Book;

③.萬事俱備,建立自己的AidlService繼承自Service,在onBind中返回一個.Stub自類的物件供其它app中使用,我的服務程式碼如下:

package com.lbb.aidltest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import com.lbb.aidltest.bean.Book;
/**
 * 作者:李少波
 * 郵箱:[email protected]
 * 日期:16/10/20
 */
public class AidlService extends Service {
    IAidlInterface.Stub mStub = new IAidlInterface.Stub() {
        @Override
        public Book getBookByIndex(int index) throws RemoteException {
            Book book = null;
            if(index ==0){
                book = new Book("第一本書",0);
            }
            return book;
        }
    };
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mStub;
    }
}

至此服務供應方程式碼編寫完畢,對了,還有一點很重要,記得在mainfest中宣告服務的隱式intent-filter,因為其它app都是用隱式方式呼叫這個服務的:

 <service android:name=".AidlService">
<intent-filter><action android:name="com.lbb.aidltest.AidlService"></action></intent-filter>
 </service>

二、呼叫其它app中可以被呼叫的服務。此處我呼叫我上一個app中的服務,前提是安裝了上一個app哦。。使用過程分兩步:
①.帶上包名拷貝上一個app中的bean和aidl檔案(包括自定義類以及介面的都要),也就是使用端要和提供端的bean的包路徑以及aidl的包路徑是一樣的,沒有路徑創造路徑也要保證一樣。
②.在Activity中愉快的引用其他app服務吧,這裡是隱式呼叫的,如果直接隱式呼叫在android 5.0之後的環境下會報”只能顯式啟動Service”的錯誤,此處用了一個網上蕩的方法,可以用隱式開啟服務了,我是這樣使用的:

public class MainActivity extends Activity {
    private IAidlInterface aidlService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Intent intent = new Intent();
        intent.setAction("com.lbb.aidltest.AidlService");
        final Intent eintent = new Intent(createExplicitFromImplicitIntent(this,intent));
        bindService(eintent,serviceConnection, Service.BIND_AUTO_CREATE);
    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            aidlService = IAidlInterface.Stub.asInterface(iBinder);
            try {
                Book book = aidlService.getBookByIndex(0);
                Log.d(MainActivity.class.getSimpleName(),"book名字: "+book.getName());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }


    public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);

        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }

        // Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);

        // Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);

        // Set the component to be explicit
        explicitIntent.setComponent(component);

        return explicitIntent;
    }
}

三、小結
1.提供端介面aidl檔案建立需要手動import 自定義類,自定義類的aidl需要全手工填寫包名並parcelable Book;
2.使用端要拷貝提供端的bean和aidl檔案,並且在android 5.0以上系統需要用以上的方式來使得隱式bindService變為顯式bind。
3.aidl呼叫第一個應用服務,不需要啟動第一個應用哦

相關推薦

android studio使用Aidl程序呼叫服務

以前就知道其大概程式碼流程,但是一直沒有敲程式碼去實現,今天將其實現了,android studio下編寫也遇到了一些小細節的問題,特此記錄一下。 既然是模擬Aidl通訊,那麼當然要編寫兩個應用了,一個提供服務給另一個應用呼叫,那麼開始吧。 一、服務提供方應

Service程序呼叫服務三部曲之AIDL詳解(三)

package com.example.client_aidl3_activity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widg

Android四大元件應用系列5——使用AIDL實現程序呼叫Service

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstan

android——實現程序訪問數據

允許 selection stat 查詢 add provider null roi auth 使用之前的SQLite存儲的應用程序。首先需要在這個應用程序中創建內容提供器,右擊com.example.administrator.exp7包→New→Other→Conten

Android學習--程序共享數據之內容提供其探究

bundle 風險 重點 比較 約束 length 通訊 this provide 什麽是內容提供器? 跨程序共享數據之內容提供器,這是個什麽功能?看到這個名稱的時候最能給我們提供信息的應該是“跨程序”這個詞了,是的重點就是這個詞,這個內容提供器的作用

Android-Messenger程序通訊

http://blog.csdn.net/lmj623565791/article/details/47017485   一.概述 我們可以在客戶端傳送一個Message給服務端,在服務端的handler中會接收到客戶端的訊息,然後進行對應的處理,處理完成後,再將結果等資

thrift語言呼叫服務,以nodejs和Java為例

使用thrift的流程: 1、下載thrift的exe,編寫thrift介面檔案,使用thrift --gen java + 檔名生成Java的介面檔案,使用thrift --gen js:node +檔名 生成nodejs介面檔案。介面檔案PrintService.th

Android Messenger程序通訊

1、目的 實現不同程序間的通訊。可以將客戶端的資料通過Message傳遞到服務端,同時服務端的資料也可以通過Message返回到客戶端。 2、原理 不同程序間的通訊通過Messenger為服務端建立介面,客戶端就可以Message傳送給服務端,交給服務端的Handler

Android Binder 程序通訊

1.基本前提知識:    1.1 程序隔離      1.LINUX 中 每個程序有自己的虛擬記憶體空間,作業系統將這種虛擬記憶體空間對映到實體記憶體空間 ,每個程序不能操作其他程序的記憶體空間;      2.只有作業系統才有許可權操作實體記憶體空間;      3

android程序通訊的4種方式

由於android系統中應用程式之間不能共享記憶體。因此,在不同應用程式之間互動資料(跨程序通訊)就稍微麻煩一些。在android SDK中提供了4種用於跨程序通訊的方式。這4種方式正好對應於android系統中4種應用程式元件:Activity、Content Prov

圖文詳解 Android Binder程序通訊機制 原理

目錄 目錄 1. Binder到底是什麼? 中文即 粘合劑,意思為粘合了兩個不同的程序 網上有很多對Binder的定義,但都說不清楚:Binder是跨程序通訊方式、它實現了IBinder介面,是連線 ServiceManager的橋樑blabla,估計大家都看暈了

Android程序通訊的四種方式

由於android系統中應用程式之間不能共享記憶體。因此,在不同應用程式之間互動資料(跨程序通訊)就稍微麻煩一些。在android SDK中提供了4種用於跨程序通訊的方式。這4種方式正好對應於android系統中4種應用程式元件:Activity、Content Provider、Broadcast和Serv

帶你一起剖析Android AIDL程序通訊的實現原理

今日科技快訊 從8月份釋出混改方案開始,中國聯通作為首批混改試點中惟一一家集團層面整體混改的央企,也是全球首例“電信運營商+網際網路巨頭”戰略融合先行試水者,一直倍受關注。而就在昨日,有業內

android中的程序通訊的實現(一)——遠端呼叫過程和aidl

android在設計理念上強調元件化,元件之間的依賴性很小。我們往往發一個intent請求就可以啟動另一個應用的activity,或者一個你不知道在哪個程序的service,或者可以註冊一個廣播,只要有這個事件發生你都可以收到,又或者你可以查詢一個contentProvider獲得你想要的資料,這其

Android中使用ContentProvider進行程序方法呼叫

需求背景 最近接到這樣一個需求,需要和別的 App 進行聯動互動,比如下載器 App 和桌面 App 進行聯動,桌面的 App 能直接顯示下載器 App 內的下載任務進度和狀態。 尋找解決方案 從需求上知道了,主要問題在如何解決跨程序的通訊上邊

Android程序通訊Binder原理分析(二)

文章目錄 1 Binder原始碼分析 1.1 Service的註冊流程 1.2 Service的獲取流程 1.3 Service的使用流程 1 Binder原始碼分析 1.1 Service的註冊流程  

Android程序通訊Binder原理分析(一)

文章目錄 1. Linux程序基礎 1.1 程序隔離 1.2 使用者空間/核心空間 1.3 核心模組/驅動 1.4 圖解 2. 為什麼要使用Binder 2.1 安全方面 2.2 效能方面(一

Android每天一個知識點+Demo—程序通訊機制AIDL入門

一 Why-為什麼要用AIDL 沙箱理念:在Android中,每個應用(Application)程式都執行在獨立的程序中,無法直接呼叫到其他應用的資源。當一個應用被執行時,一些操作是被限制的,比如訪問記憶體,訪問感測器等等。 好處:這也保證了當其中一個程式出現異常而不會影

Android程序通訊:binder機制原理

個人閱讀收穫 通過binder驅動我們可以減少一次io操作,從而減少了我們程序通訊的花費的資源,加快了程序間通訊的速度。我們使用到了Linux的mmap()操作,從而實現了程序間的接收快取區與程序的空間區的對映,從而少了一次io操作。我們的客戶端會發送資訊通過我們io操作講

Android程序喚醒APP,啟動指定頁面

1 自定義啟動協議。 AndroidManifest.xml中配置通過喚起啟動的頁面。 <!--喚醒app--> <activity android:name=".SecondActivity" andro