TSDK (Transfer SDK)

解决游戏接入渠道SDK的繁琐工作。做到一次接入,通过打包工具生成不同的渠道安装包。

SDK接入框架

闪屏接入

定义一个Activity继承TSplashActivity

public class TestSplashActivity extends TSplashActivity {

    @Override
    protected void onCreate(Bundle savedInstance) {
        //设置SDK的横竖屏
        setLandScape(true);
        super.onCreate(savedInstance);
    }
    
    public int getBackgroundColor() {
        //当闪屏PNG图片无法铺满部分机型的屏幕时,设置与闪屏颜色配合的背景色会给用户更好的体验
        return Color.WHITE;
    }
    
    @Override
    public void onSplashStop() {
        //闪屏结束后,启动游戏的Activity
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        this.finish();
    }
} 

AndroidManifest.xml 配置修改



    android:configChanges="orientation|keyboardHidden|screenSize"
    android:screenOrientation="portrait" >
    
        

        
    












接入函数调用

方法 描述
login TSDK的登陆入口
logout TSDK的登陆注销
pay TSDK的支付入口
quit 游戏退出调用
submitExtendData 上传扩展数据
onResume SDK生命周期函数,在activity的onResume 中调用
onPause SDK生命周期函数,在activity的onPause中调用
onDestroy SDK生命周期函数,在activity的onPause中调用

TSDK入口类为TSDKUserCenter,主要函数如下:

方法 描述
login TSDK的登陆入口
logout TSDK的登陆注销
pay TSDK的支付入口
quit 游戏退出调用
submitExtendData 上传扩展数据
onResume SDK生命周期函数,在activity的onResume 中调用
onPause SDK生命周期函数,在activity的onPause中调用
onDestroy SDK生命周期函数,在activity的onPause中调用

函数介绍

  • 登录介绍
    调用TSDK的login登录,会调起相对应的SDK登录流程

    public static void login(Context context, GameParams params, ILoginCallback callback)
    用于登录融合SDK。登录成功或取消登录ILoginCallback 均能监听到。

| 参数         | 描述                                       |能否为空|
| :------     | :------------------------------------------| --   |
| context     | 当前Activity的context                       | 否   |
| params      | 用于传递游戏登录的参数                         | 否   |
| callback    | 监听登录成功或取消登录的回调                    | 否   |

| GameParams  属性| 描述                                        |
| :------        | :------------------------------------------ |
| frm            | 来源                                        |
| fdata          | 来源描述                                     | 

LoginResponse 包含下列字段

    public int code;       //登陆状态CODE_SUCCESS = 1;  CODE_FAIL = -1;
    public String msg;     //code=CODE_FAIL ,是msg会有相关的内容
    public String uid;     // 我方给出的不冲突用户id
    public String channel; //渠道标识,用来区分用户来自哪个渠道
    public String access_token;//令牌
    public String c_uid;   //渠道返回的uid,TSDK内部使用,请勿使用,一般情况为空;
    public int adult;      //成年-1未成年, 0未知, 1成年
  • 注销登录介绍
    调起融合SDK的logout注销,会调起相应的SDK注销流程

    public static void logout(Context context, GameParams params,ILogoutCallback callback)
    用于注销登录。

    参数 描述 能否为空
    context 当前Activity的context
    params 用于传递游戏注销登录的参数
    callback 监听注销登录的回调
    GameParams 属性 描述
    暂无
LogoutResponse 包含下列字段

    public int code;       //登出状态CODE_SUCCESS = 1;  CODE_FAIL = -1;
    public String msg;     //code=CODE_FAIL ,是msg会有相关的内容    
  • 支付接口介绍
    调起融合SDK的pay支付,会调起相应的SDK支付流程

    public static void pay(Context context, GameParams params, IPayCallback callback)
    用于支付的方法。

    参数 描述 能否为空
    context 当前Activity的context
    params 用于传递游戏支付的参数
    callback 监听支付的回调
    GameParams 属性 描述
    uid 用户id
    access_token 令牌
    productId 商品id
    productName 商品名
    price 金额(元)
    serverId 服务器id
    roleId 角色id
    roleName 角色名
    roleLevel 角色等级
    gold 游戏币,如钻石
    extension 扩展字段

    PayResponse 包含下列字段

      public int code;       //支付返回状态CODE_SUCCESS = 1;    CODE_FAIL = -1;
      public String msg;     //code=CODE_FAIL ,是msg会有相关的内容    
    
  • 游戏退出
    调起融合SDK的quit退出,会调起相应的SDK退出流程

    public static void quit(Context context, GameParams params, IQuitCallback callback)
    用于调起SDK的退出框的方法。

    参数 描述 能否为空
    context 当前Activity的context
    params 用于传游戏退出的参数
    callback 监听退出的回调
    GameParams 属性 描述
    暂无

    回调说明

      //渠道带有退出框
      @Override
      public void quitCallback(QuitResponse quitResponse) {
          Toast.makeText(this, "退出回调", Toast.LENGTH_SHORT).show();
          if (quitResponse != null) {
              LogUtils.d(quitResponse.toString());
          }
          finish();
      }
    
      //渠道不带退出框
      @Override
      public void onNo3rdQuitCallback(QuitResponse quitResponse) {
          quitDialog();
      }
    
      private void quitDialog() {
          AlertDialog.Builder builder = new Builder(this);
          builder.setMessage("确定要退出吗?");
          builder.setTitle("提示");
          builder.setPositiveButton("确认",
              new android.content.DialogInterface.OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                      dialog.dismiss();
                      finish();
                  }
              });
          builder.setNegativeButton("取消",
              new android.content.DialogInterface.OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                      dialog.dismiss();
                  }
              });
          builder.create().show();
      }
    

    QuitResponse 包含下列字段

      public int code;       //支付返回状态CODE_SUCCESS = 1;    CODE_FAIL = -1;
      public String msg;     //code=CODE_FAIL ,是msg会有相关的内容    
    
  • 上传扩展数据
    调起融合SDK的上传扩展数据接口,请在用户选择角色以及服务器后调用,否则无法正常支付

    public static void submitExtendData(Context context, GameParams params)

    参数 描述 能否为空
    context 当前Activity的context
    params 用于传扩展字段
    GameParams 属性 描述
    score 分数
    topnid 可选参数,排行榜标识,使用该参数需要确认对应ID的排行榜已经开通
    roleId 角色id
    roleName 角色名
    roleLevel 角色等级
    zoneId 当前登录的游戏区服ID,必须为数字,且不能为0,若无,传入1
    zoneName 当前登录的游戏区服名称,不能为空,不能为null,若无,传入游戏名称+”1区”,如”刀塔传奇1区”
    balance balance 当前用户游戏币余额,必须为数字,若无,传入0
    vip vip 当前用户VIP等级,必须为数字,若无,传入1
    partyName partyName 当前用户所属帮派,不能为空,不能为null,若无,传入”无帮派

    上传数据接口需在三处调用,分别为进入服务器、玩家创建用户角色、玩家升级,有如下二点需注意:

    a)若游戏中无对应接口功能,如游戏中无需创建角色,则可根据自身情况在合适位置进行调用,如登录成功后;
    b)在上传游戏数据时,若存在无对应字段值的情况,可传入默认值,具体参见数据组成部分;

  • 生命周期函数调用

     public static void onResume(Context context)
     public static void onPause(Context context)
     public static void onDestroy(Context context)
     SDK的生命周期函数,在程序的主Activity的生命周期相应函数中调用 
    
抽象工厂

定义一个抽象工厂,规范需要实现的接入函数

public interface IChannel {

    public void init(Context context, boolean isLandScape, IChannelInitCallback callback);

    public void login(GameParams params);

    public void pay(GameParams params);

    public void logout(GameParams params);

    public void quit(GameParams params);

    public void onResume(Context context);

    public void onPause(Context context);

    public void onStop(Context context);

    public void onDestroy(Context context);

    public void submitExtendData(Context context, GameParams params);

}

调用对应的工厂实例

根据配置在 manifest 文件中的 CHANNEL_KEY 调用对应的工厂实例

public class DispatchChannel {

    private static IChannel channel;
    private static final String CHANNEL_KEY = "CHANNEL_KEY";

    public static IChannel getChannel(Context context){
        if(channel == null) {
            ChannelFactory cf = new ChannelFactory();
            String channelString = ChannelUtil.getChannel(context, SDKTools.getMetaData(context, CHANNEL_KEY));
            channel = cf.createChannel(channelString);
        }
        return channel;
    }
}

各渠道接入实现

AndroidManifest.xml中配置要调用的渠道以及对应渠道设置的代理Application












定义一个具体的渠道类实现 抽象工厂接口

public class Channel360 extends BaseChannel implements IChannel

调用渠道登陆成功后和服务端做一次用户绑定,返回用户信息

支付前请求一次服务端的支付参数信息,再调起渠道SDK支付

打包工具

1. 解母包(copy 到对应的工作目录)

apktool d -f -o $game_path $game_path${apk_suffix}

2. 资源处理

2.1 准备对应渠道的资源文件
assets(copy 到对应的工作目录)
    t_splash_images //闪屏文件夹,不存在或为空则没有配闪屏
    ... //渠道此文件夹下的资源
libs (copy 到对应的工作目录 lib 下)
    ... //渠道的非 .jar 文件
res (copy 到对应的工作目录)
    ...
    如碰到 strings.xml, styles.xml, colors.xml, dimens.xml, ids.xml, attrs.xml ... 则合并其内容
    带有对应渠道角标的 ic_launcher 对应的文件夹        
classes.dex (具体接入渠道的 .dex 文件) 后面会用到

具体命令如下

cp -R -f  $game_path/* $channel_name/

cp -R -f $config_name/AndroidManifest.xml $channel_name/

cp -R -f $config_name/assets/* $channel_name/assets/

cp -R -f $config_name/libs/* $channel_name/lib/

cp -R -f $config_name/res/* $channel_name/res/

# 合并strings.xml ...
$tool/xml -f $game_path/res/values/ -s $channel_name/res/values/ -t $config_name/res/values/

if [ -d "$config_name/channel_icon" ];then
    # 合成icon
    $tool/icon -f $channel_name/res/drawable-ldpi/$icon_name.png -s $channel_name/res/drawable-ldpi/$icon_name.png -t $config_name/channel_icon/ldpi.png -x 0 -y 0
    $tool/icon -f $channel_name/res/drawable-mdpi/$icon_name.png -s $channel_name/res/drawable-mdpi/$icon_name.png -t $config_name/channel_icon/mdpi.png -x 0 -y 0
    $tool/icon -f $channel_name/res/drawable-hdpi/$icon_name.png -s $channel_name/res/drawable-hdpi/$icon_name.png -t $config_name/channel_icon/hdpi.png -x 0 -y 0
    $tool/icon -f $channel_name/res/drawable-xhdpi/$icon_name.png -s $channel_name/res/drawable-xhdpi/$icon_name.png -t $config_name/channel_icon/xhdpi.png -x 0 -y 0
    $tool/icon -f $channel_name/res/drawable-xxhdpi/$icon_name.png -s $channel_name/res/drawable-xxhdpi/$icon_name.png -t $config_name/channel_icon/xxhdpi.png -x 0 -y 0
    $tool/icon -f $channel_name/res/drawable-xxxhdpi/$icon_name.png -s $channel_name/res/drawable-xxxhdpi/$icon_name.png -t $config_name/channel_icon/xxxhdpi.png -x 0 -y 0
fi

3. 处理 AndroidManifest.xml文件, 并覆盖到对应的工作目录

3.1 渠道权限添加
3.2 包名修改
3.3 activity name属性为全路径
3.4 渠道 activity 等内容合并
3.5 渠道参数在 meta-data
3.6自有的参数 meta-data
3.7具体对应的 CHANNEL_KEY meta-data
3.8 具体对应的 T_APPLICATION_PROXY_NAME meta-data

4. 生成 R.java 文件

4.1 建一个gen文件夹
mkdir -p $channel_name/gen
4.2 执行 aapt p ... 命令
 aapt p -f -m -J $channel_name/gen -S $channel_name/res -I $tool/android.jar -M $channel_name/AndroidManifest.xml

5. 将 R.java 编译成对应的 .class 文件

 javac  -encoding UTF-8 $channel_name/gen/${package}${package_suffixs[$index]}/R.java

6. 将生成的 .class 文件生成 .dex 文件

$tool/dx --no-strict --dex --output=$channel_name/Rclasses.dex $channel_name/gen/$package/${package_suffixs[$index]}

7. 将生成的 .dex 文件 编译成 smali格式的文件合并到 (1)中复制的对应工作目录下的 smali 文件夹

java -jar $tool/baksmali.jar $channel_name/Rclasses.dex -o $channel_name/smali/

8. 将 (2)中准备好的 classes.dex 编译成 smali 格式的文件合并到 (1)中复制的对应工作目录下的 smali 文件夹

java -jar $tool/baksmali.jar $config_name/classes.dex -o $channel_name/smali/

9. 使用 apktool b ... 命令打包

apktool b -b ${channel_name}/

10. 使用 jarsinger 签名

jarsigner -keystore $tool/${keystore} -storepass ${keypass} -signedjar ${channel_name}/dist/${game_name}_signed.apk ${channel_name}/dist/${game_name}.apk "${keyalias}"

11. zipalign 命令进行 4 字节对齐优化产生最终的 apk 文件

$tool/zipalign -f 4 ${channel_name}/dist/${game_name}_signed.apk $dir/apk/${game_name}/${channel}.apk

TSDK 原理

登陆机制

1、 客户端接入 TSDK 框架,根据当前具体是哪个 SDK 渠道,调用登陆界面,然后传入用户名和密码,进行SDK登陆操作
2、 SDK登陆成功,返回 cid 等信息
3、 TSDK会拿 cid 以及游戏申请的 T_G_ID,渠道号等信息访问 server 进行登陆认证
4、 server 调用渠道服务器获取 userinfo 进行绑定,返回统一的 userinfo
5、TSDK回调游戏相关的信息
6、 游戏拿到登陆的 userinfo

支付机制

1、 游戏客户端拿用户id和一些支付参数调起 TSDK 的支付模块
2、 TSDK 访问服务端申请订单号
3、 服务端生成订单记录返回
4、 TSDK 用支付参数和订单号调起渠道 SDK,将生成的订单号放到渠道 SDK 支付参数中
5、 渠道 SDK 支付成功,返回状态,同时渠道 SDK 服务器会通知 TSDK 服务端
6、 TSDK 服务收到渠道的充值回调后会给渠道 SDK 服务端返回一个状态,然后回调游戏提供的支付回调地址
7、 TSDK 收到支付返回的状态回调游戏的支付回调
8、 游戏拿到支付结果信息

你可能感兴趣的:(TSDK (Transfer SDK))