天天看點

Android不同APP之間的喚起和傳參場景再現舉個栗子時序圖技術方案

  • 場景再現
  • 舉個栗子
  • 時序圖
  • 技術方案
    • URL Scheme
      • URL Scheme 協定格式
      • Android 實作過程
        • APP A 發起喚起動作
        • APP B 被喚起

場景再現

在開發過程中,會發現有一些業務是需要通過喚起自家不同産品之間的喚起和一些業務操作。例如,可以在産品A直接打開産品B,并且需要在喚起的時候單點登入到B當中。這樣可以減少使用者的登入操作,有一個比較好的使用者體驗。

舉個栗子

公司有一個 APP A 需要打開 APP B 的時候,如果使用者已經在 A 登入了,那打開 B 的時候也需要是登入狀态。

時序圖

從需求描述,我們可以通過技術讨論,用以下時序圖可以描述。

時序圖我們可以很清晰的明白我們在不同的子產品中所擔任的角色和所應該做的事兒。那之後我們就可以進行一個技術方案選型了。

技術方案

APP B

進行token、userId進行校驗這一步驟還算簡單。但是問題在于我們的

APP A

喚起

APP B

的過程該如何實作。

URL Scheme

如果考慮不同平台中的一緻性的話,該方案是最優解。因為這種方案适用于

android

iOS

web

三種平台。

android中的scheme是一種頁面内跳轉協定,是一種非常好的實作機制,通過定義自己的scheme協定,可以非常友善跳轉app中的各個頁面;通過scheme協定,伺服器可以定制化告訴App跳轉那個頁面,可以通過通知欄消息定制化跳轉頁面,可以通過H5頁面跳轉頁面等。

URL Scheme 協定格式

scheme 最常見的,也是我們最熟悉的,就是

栗子1

所列的,就是我們平常所說的位址。

栗子3

是屬于自定義的scheme協定,一般用于自家産品的場景跳轉等等,直接打開是沒有效的。

// 栗子1
https://baidu.com/app/download?type=android

// 栗子2
http://localhost:8080/index.html

// 栗子3
alipay://platformtype/pay?key1=value1&key2=value2
           

劃重點

  1. scheme 協定:栗子當中的https、http、alipay
  2. host 位址域:baidu.com、localhost、platformtype
  3. port 端口:8080(http 協定預設 80 端口、https 協定預設 443 端口,一般預設端口的時候可以忽略端口号,在位址當中不必展現)
  4. 頁面\或者具體位址:/app/download、/index.html、/pay
  5. URL參數:type、key1、key2,對應的值依次為:android、value1、value2

Android 實作過程

APP A 發起喚起動作

這裡需要注意的是,如果手機沒有安裝

APP B

APP A

沒有做好判斷和異常處理,是會導緻

APP A

閃退的!

private void openYDDJ() {
    if (isClientAvailable(mContext, "com.padakill.appA")) {
        Intent intent = new Intent("android.intent.action.VIEW");
        Uri uri = Uri.parse("jumpscheme://com.test.padakill/jumpFrom=APP A&userId=f23dada3eab3daefg&token=fw12ea2754dba");
        intent.setData(uri);
        startActivity(intent);
    } else {
        // TODO 打開下載下傳連結
    }
}

/**
 * 判斷是否存在該應用
 *
 * @param context   上下文
 * @param appName   APP B 的包名
 * @return  如果存在該應用,則傳回true;否則傳回false
 */
private boolean isClientAvailable(Context context, String appName) {
    final PackageManager packageManager = context.getPackageManager();
    List<PackageInfo> pinfo = packageManager.getInstalledPackages();
    if (pinfo != null) {
        for (int i = ; i < pinfo.size(); i++) {
            String pn = pinfo.get(i).packageName;
            if (pn.equalsIgnoreCase(appName)) {
                return true;
            }
        }
    }
    return false;
}
           

APP B 被喚起

  1. AndroidManifest.xml

    中配置接受 schemeURL 協定的 activity
    <activity
        android:name="com.padakill.appB.JumpActivity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
        <intent-filter>
            <!-- 這裡即我們前面要求的 schemeURL 規則 -->
            <data
                android:host="com.test.padakill"
                android:scheme="jumpscheme"/>
    
                <!-- 必須添加的屬性 -->
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>
               
  2. 在 activity 中擷取參數等資訊,然後進行token驗證等業務操作
public class JumpActivity extends Activity {

    @Override
    private void onCreate(Bundle saveInstance) {
        super.onCreate(saveInstance);
        setContentView(R.layout.jumpActivity);

        Uri data = getIntent().getData();
        String uerId = data.getQueryParameter("userId");
        String token = data.getQueryParameter("token");

        // TODO 拿到參數之後即可進行該操作了
    }
}