做过软件开发的想必都或多或少的接过各种sdk。接一个sdk不难,但是要做到接了十个不同或相同功能的sdk,还要做到代码结构清晰,维护方便,就不是一件简单的事情。
博主在以前在游戏公司有幸参与打造统一第三方SDK接入,现在,博主决定在新的要负责新项目的用户登录,分享等模块,为了让以后不再苦逼,决定打造一个自己专属的统一第三方SDK接入框架。
对于整个框架我们希望到达下面的几个点:
1.相同功能的sdk统一管理(目前暂时有登录,支付,发享模块)
2.各家单独接入,这样有利于各家的维护升级,添加或者去除
3.整个框架不出现与具体业务相关的逻辑
框架的下载链接为:http://download.csdn.net/detail/phone_0405/9448106
本系列分享包括:
1.整个框架的思路以及实现
2.QQsdk登陆以及分享的接入
3.微博sdk的登陆以及分享的接入
4.微信sdk的登陆以及分享的接入
5.微信支付sdk的接入
6.支付宝支付sdk的接入
1.整个框架的思路以及实现
首先我们先定义的各家sdk接入的组件接口Component以及管理这些组建的Platform
package com.wang.wsdk;
import android.app.Activity;
import android.content.Intent;
public abstract class Component<T> {
private final ComponentType type;
private final String name;
public Component(String name, ComponentType login) {
this.name = name;
this.type = login;
}
public ComponentType getType() {
return type;
}
public String getName() {
return name;
}
protected Activity activity = null;
public final void setup(Activity activity) {
this.activity = activity;
}
protected boolean isRunning = false;
public boolean isRunning() {
return isRunning;
}
protected ThirdListener<T> mListener;
public void sendError(String reason) {
isRunning = false;
mListener.onError(reason);
}
public void sendCancel() {
isRunning = false;
mListener.onCancel();
}
public void sendSuccess(T info) {
isRunning = false;
mListener.onSuccess(info);
}
public void sendLoading() {
mListener.onLoading();
}
public void onCreate() {
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
public void onStart() {
}
public void onRestart() {
}
public void onResume() {
}
public void onPause() {
}
public void onStop() {
}
public void onDestroy() {
}
public void onBackPressed(){
}
}
package com.wang.wsdk;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
public class Platform {
protected ArrayList<Component> components = new ArrayList<Component>();
protected Activity activity;
protected String activityName;
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
private boolean isSetup = false;
public boolean isSetup(){
return isSetup;
}
public void setup(final Activity activity, List<Component> compArray) {
this.activity = activity;
components.addAll(compArray);
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.setup(this.activity);
c.onCreate();
}
activityName = "";
isSetup = true;
}
public void cleanup() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
isSetup = false;
}
public void onStart() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onStart();
}
}
public void onRestart() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onRestart();
}
}
public void onResume() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onResume();
}
}
public void onPause() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onPause();
}
}
public void onStop() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onStop();
}
}
public void onDestroy() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onDestroy();
}
}
public void onBackPressed() {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onBackPressed();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
c.onActivityResult(requestCode, resultCode, data);
}
}
}
接着我们对根据不同的功能实现编写功能的组件的抽象类,以支付模块为例 有支付组建PayComponent,以及对于支付的管理类,如:PayPlatform
package com.wang.wsdk.pay;
import com.wang.wsdk.Component;
import com.wang.wsdk.ComponentType;
import com.wang.wsdk.ThirdListener;
/**
* 支付模块
*
* @author wangjf
*/
public abstract class PayComponent extends Component<PayInfo> {
public PayComponent(String name) {
super(name, ComponentType.PAY);
}
protected PayInfo mPayInfo;
public void pay(PayInfo payInfo, ThirdListener<PayInfo> listener) {
mListener = listener;
if (!isInstalledClient()) {
sendError("noClient");
return;
}
mPayInfo = payInfo;
payImpl();
isRunning = true;
}
protected abstract void payImpl();
public abstract Object getAPI();
public abstract boolean isInstalledClient();
}
package com.wang.wsdk.pay;
import java.util.Iterator;
import com.wang.wsdk.Component;
import com.wang.wsdk.ComponentType;
import com.wang.wsdk.Platform;
/**
* 支付组建管理器
*
* @author wangjf
*
*/
public class PayPlatform extends Platform {
private static class SingletonHolder {
public static final PayPlatform instance = new PayPlatform();
}
public static PayPlatform getInstance() {
return SingletonHolder.instance;
}
public PayComponent getPayComponent(final String name) {
Iterator<Component> it = components.iterator();
while (it.hasNext()) {
Component c = it.next();
if (c.getType() == ComponentType.PAY
&& c.getName().compareTo(name) == 0) {
return (PayComponent) c;
}
}
return null;
}
}
然后我们只要根据对于的sdk实现对应的支付接口,已支付宝为例
package com.wang.wsdk.alipay;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import com.alipay.sdk.app.PayTask;
import com.wang.wsdk.pay.PayComponent;
public class Pay extends PayComponent implements IAlipay {
private static final int SDK_PAY_FLAG = 1;
private static final int SDK_CHECK_FLAG = 2;
public Pay() {
super("alipay");
}
@Override
public void onCreate() {
super.onCreate();
}
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG: {
PayResult payResult = new PayResult((String) msg.obj);
String resultStatus = payResult.getResultStatus();
if (TextUtils.equals(resultStatus, "9000")) {
sendSuccess(mPayInfo);
} else {
sendError("");
}
break;
}
case SDK_CHECK_FLAG: {
if(msg.arg1 == 0){
sendError("noClient");
}else{
sendPay();
}
break;
}
default:
break;
}
};
};
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
@Override
public Object getAPI() {
return null;
}
@Override
public boolean isInstalledClient() {
return true;
}
@Override
protected void payImpl() {
check();
}
private void check() {
Runnable checkRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask payTask = new PayTask(activity);
// 调用查询接口,获取查询结果
boolean isExist = payTask.checkAccountIfExist();
Message msg = new Message();
msg.what = SDK_CHECK_FLAG;
msg.arg1 = isExist ? 1 : 0;
mHandler.sendMessage(msg);
}
};
Thread checkThread = new Thread(checkRunnable);
checkThread.start();
}
/**
* call alipay sdk pay. 调用SDK支付
*/
public void sendPay() {
String orderInfo = getOrderInfo(mPayInfo.getSubject(), mPayInfo.getBoby(), mPayInfo.getTotalFee());
/**
* 特别注意,这里的签名逻辑需要放在服务端,切勿将私钥泄露在代码中!
*/
String sign = sign(orderInfo);
try {
/**
* 仅需对sign 做URL编码
*/
sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
/**
* 完整的符合支付宝参数规范的订单信息
*/
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(activity);
// 调用支付接口,获取支付结果
String result = alipay.pay(payInfo, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start();
}
private String sign(String content) {
return AlipaySignUtils.sign(content, RSA_PRIVATE);
}
private String getSignType() {
return "sign_type=\"RSA\"";
}
/**
* create the order info. 创建订单信息
*/
private String getOrderInfo(String subject, String body, String price) {
// 签约合作者身份ID
String orderInfo = "partner=" + "\"" + PARTNER + "\"";
// 签约卖家支付宝账号
orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
// 商户网站唯一订单号
orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";
// 商品名称
orderInfo += "&subject=" + "\"" + subject + "\"";
// 商品详情
orderInfo += "&body=" + "\"" + body + "\"";
// 商品金额
orderInfo += "&total_fee=" + "\"" + price + "\"";
// 服务器异步通知页面路径
orderInfo += "¬ify_url=" + "\"" + "http://api.mibolive.com:9090/mibo/mobile/pay/alipay_notify" + "\"";
// 服务接口名称, 固定值
orderInfo += "&service=\"mobile.securitypay.pay\"";
// 支付类型, 固定值
orderInfo += "&payment_type=\"1\"";
// 参数编码, 固定值
orderInfo += "&_input_charset=\"utf-8\"";
// 设置未付款交易的超时时间
// 默认30分钟,一旦超时,该笔交易就会自动被关闭。
// 取值范围:1m~15d。
// m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。
// 该参数数值不接受小数点,如1.5h,可转换为90m。
orderInfo += "&it_b_pay=\"30m\"";
// extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";
// 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空
//orderInfo += "&return_url=\"m.alipay.com\"";
// 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)
// orderInfo += "&paymethod=\"expressGateway\"";
return orderInfo;
}
private String getOutTradeNo() {
return mPayInfo.getTradeNo();
}
}
现在,我已经以支付为例,介绍完了整个sdk的框架,用户和发享也是一样的。
后面,我们将只要在需要调用sdk的时候先初始化对应的组建,然后调用对于的方法就好了
//初始化支付组件
private void setupPayPlatform() {
ArrayList<Component> components = new ArrayList<Component>();
components.add(new com.wang.wsdk.weixin.Pay());
components.add(new com.wang.wsdk.alipay.Pay());
PayPlatform.getInstance().setup(this, components);
PayPlatform.getInstance().setActivityName("AlipayActivity");
}
//支付
private void pay(PayInfo data){
PayComponent mPayComponent = PayPlatform.getInstance().getPayComponent("alipay");
mPayComponent.pay(data, mUiPayCallback);
}
对于整个框架我们希望到达下面的几个点:
1.相同功能的sdk统一管理(目前暂时有登录,支付,发享模块)
2.各家单独接入,这样有利于各家的维护升级,添加或者去除
3.整个框架不出现与具体业务相关的逻辑
首先我们先定义的各家sdk接入的组件接口Component以及管理这些组建的基类