- 場景再現
- 舉個栗子
- 時序圖
- 技術方案
- URL Scheme
- URL Scheme 協定格式
- Android 實作過程
- APP A 發起喚起動作
- APP B 被喚起
- URL Scheme
場景再現
在開發過程中,會發現有一些業務是需要通過喚起自家不同産品之間的喚起和一些業務操作。例如,可以在産品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
劃重點
- scheme 協定:栗子當中的https、http、alipay
- host 位址域:baidu.com、localhost、platformtype
- port 端口:8080(http 協定預設 80 端口、https 協定預設 443 端口,一般預設端口的時候可以忽略端口号,在位址當中不必展現)
- 頁面\或者具體位址:/app/download、/index.html、/pay
- 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 被喚起
- 在
中配置接受 schemeURL 協定的 activityAndroidManifest.xml
<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>
- 在 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 拿到參數之後即可進行該操作了
}
}