見識(shí)2分鐘集成微信和支付寶支付的威力

在開發(fā)的APP中項(xiàng)目集成了微信跟支付寶支付捧存,分別是在訂單確認(rèn)頁面,訂單列表以及訂單詳情里面都需要進(jìn)行支付,并且需要在當(dāng)前界面處理支付結(jié)果。

之前的處理是將代碼拷貝了三份,后來隨著項(xiàng)目越來越大春缕,感覺比較low。

于是打算重構(gòu)一下支付模塊艘蹋,下面分享一下重構(gòu)的整個(gè)過程锄贼。

支付寶支付

支付寶的集成比較簡單,按照官方文檔來集成女阀,一般是比較順利的宅荤。

不過當(dāng)時(shí)做的時(shí)候簽名一直不成功屑迂,但是跟文檔是一模一樣的,后來無意中發(fā)現(xiàn)是orderInfo的拼接順序跟簽名的順序不一樣導(dǎo)致的冯键。

所以要么在本地簽名惹盼,要么在服務(wù)端簽名,千萬不要一邊拼接另一邊簽名琼了,這樣會(huì)導(dǎo)致orderInfo的拼接順序跟簽名的順序不一樣失敗逻锐。

▍特點(diǎn):

1.返回的結(jié)果可以實(shí)時(shí)通知當(dāng)前頁面
因?yàn)槭窃谝粋€(gè)類中夫晌,我們只需要在修改AlipayActivity的構(gòu)造方法的時(shí)候傳入一個(gè)接口雕薪,在支付寶支付返回給當(dāng)前調(diào)用的界面就OK了,不管是Activity晓淀,F(xiàn)ragment所袁,或者是Adapter都是可以的。

2.不需要簽名
在調(diào)試的時(shí)候不管是debug模式還是release模式凶掰,都可以進(jìn)行調(diào)試燥爷。

3.用戶不需要安裝微信客戶端
支付寶有自帶的H5頁面,不安裝客戶端也可以正常支付

微信支付

相對(duì)于支付寶支付懦窘,微信支付就稍微麻煩一下前翎,而且文檔資料比較少,一定要嚴(yán)格按照文檔的規(guī)范畅涂,不然出問題了港华,比較麻煩。

▍特點(diǎn):

1.返回的結(jié)果在固定的頁面
微信支付比較坑的一點(diǎn)就是午衰,他的回調(diào)必須是在固定的包名:項(xiàng)目包名+wxapi,而且名稱是WXPayEntryActivity立宜。

2.必須簽名
所以開發(fā)的時(shí)候即使是debug模式也必須帶上簽名

3.需要檢測用戶是否安裝微信以及微信的版本
必須進(jìn)行校驗(yàn),不然他只會(huì)返回給你一個(gè)code臊岸,然后并不會(huì)告訴你為什么失敗橙数,就是這么任性。

封裝之路

下面借用stay大神的What-How-Why的思路對(duì)這個(gè)支付方式進(jìn)行了重構(gòu)

▍what

我們希望在支付的時(shí)候傳入一個(gè)支付的對(duì)象帅戒,支付需要的參數(shù)就能夠進(jìn)行支付灯帮,并且能夠返回給我們支付的結(jié)果。

▍how

1.傳參不一樣
定義一個(gè)基類逻住,讓支付參數(shù)對(duì)象繼承這個(gè)基類钟哥。

支付參數(shù)基類

public class BasePayBean implements Serializable {
}

支付寶支付參數(shù)

public class AliPayBean extends BasePayBean {
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    private String code;
    private String message;
    private DataBean data;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public DataBean getData() {
        return data;
    }
    public void setData(DataBean data) {
        this.data = data;
    }
    public static class DataBean {
        private String _input_charset;
        private String body;
        private String notify_url;
        private String out_trade_no;
        private String partner;
        private String payment_type;
        private String return_url;
        private String seller_id;
        private String service;
        private String subject;
        private String total_fee;
        private String sign_string;
        private String sign_type;
        private String sign;
        public String get_input_charset() {
            return _input_charset;
        }
        public void set_input_charset(String _input_charset) {
            this._input_charset = _input_charset;
        }
        public String getBody() {
            return body;
        }
        public void setBody(String body) {
            this.body = body;
        }
        public String getNotify_url() {
            return notify_url;
        }
        public void setNotify_url(String notify_url) {
            this.notify_url = notify_url;
        }
        public String getOut_trade_no() {
            return out_trade_no;
        }
        public void setOut_trade_no(String out_trade_no) {
            this.out_trade_no = out_trade_no;
        }
        public String getPartner() {
            return partner;
        }
        public void setPartner(String partner) {
            this.partner = partner;
        }
        public String getPayment_type() {
            return payment_type;
        }
        public void setPayment_type(String payment_type) {
            this.payment_type = payment_type;
        }
        public String getReturn_url() {
            return return_url;
        }
        public void setReturn_url(String return_url) {
            this.return_url = return_url;
        }
        public String getSeller_id() {
            return seller_id;
        }
        public void setSeller_id(String seller_id) {
            this.seller_id = seller_id;
        }
        public String getService() {
            return service;
        }
        public void setService(String service) {
            this.service = service;
        }
        public String getSubject() {
            return subject;
        }
        public void setSubject(String subject) {
            this.subject = subject;
        }
        public String getTotal_fee() {
            return total_fee;
        }
        public void setTotal_fee(String total_fee) {
            this.total_fee = total_fee;
        }
        public String getSign_string() {
            return sign_string;
        }
        public void setSign_string(String sign_string) {
            this.sign_string = sign_string;
        }
        public String getSign_type() {
            return sign_type;
        }
        public void setSign_type(String sign_type) {
            this.sign_type = sign_type;
        }
        public String getSign() {
            return sign;
        }
        public void setSign(String sign) {
            this.sign = sign;
        }
    }
}

微信支付參數(shù)

public class WeChatBean extends BasePayBean {
    private String code;
    private String message;
    private DataBean data;
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public DataBean getData() {
        return data;
    }
    public void setData(DataBean data) {
        this.data = data;
    }
    public static class DataBean {
        private String appid;
        private String partnerid;
        private String prepayid;
        private String package_;
        private String noncestr;
        private String timestamp;
        private String sign;
        public String getAppid() {
            return appid;
        }
        public void setAppid(String appid) {
            this.appid = appid;
        }
        public String getPartnerid() {
            return partnerid;
        }
        public void setPartnerid(String partnerid) {
            this.partnerid = partnerid;
        }
        public String getPrepayid() {
            return prepayid;
        }
        public void setPrepayid(String prepayid) {
            this.prepayid = prepayid;
        }
        public String getPackage_() {
            return package_;
        }
        public void setPackage_(String package_) {
            this.package_ = package_;
        }
        public String getNoncestr() {
            return noncestr;
        }
        public void setNoncestr(String noncestr) {
            this.noncestr = noncestr;
        }
        public String getTimestamp() {
            return timestamp;
        }
        public void setTimestamp(String timestamp) {
            this.timestamp = timestamp;
        }
        public String getSign() {
            return sign;
        }
        public void setSign(String sign) {
            this.sign = sign;
        }
    }

2.支付對(duì)象不一樣
定義一個(gè)泛型接口,讓支付對(duì)象去繼承這個(gè)接口

泛型接口

public interface BasePayWay {
void startPay(Activity activity, T t, PayCallBack payCallback);
}

支付寶支付對(duì)象

public class AliPayWay implements BasePayWay {
//商戶PID
public static final String PARTNER = "";
//商戶收款賬號(hào)
public static final String SELLER = "";
//商戶私鑰,pkcs8格式
public static String RSA_PRIVATE = "";
public static final int SDK_PAY_FLAG = 1;
public static final int SDK_CHECK_FLAG = 2;
public PayCallBack mPayCallBack;
private Activity mActivity;
//--------支付寶支付回調(diào)-----
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case AliPayWay.SDK_PAY_FLAG: {
                PayResult payResult = new PayResult((String) msg.obj);
                // 支付寶返回此次支付結(jié)果及加簽鄙信,建議對(duì)支付寶簽名信息拿簽約時(shí)支付寶提供的公鑰做驗(yàn)簽
                String resultStatus = payResult.getResultStatus();
                // 判斷resultStatus 為“9000”則代表支付成功瞪醋,具體狀態(tài)碼代表含義可參考接口文檔
                if (TextUtils.equals(resultStatus, "9000")) {
                    mPayCallBack.onResponse(0);
                } else {
                    // 判斷resultStatus 為非“9000”則代表可能支付失敗
                    // “8000”代表支付結(jié)果因?yàn)橹Ц肚涝蚧蛘呦到y(tǒng)原因還在等待支付結(jié)果確認(rèn),最終交易是否成功以服務(wù)端異步通知為準(zhǔn)(小概率狀態(tài))
                    if (TextUtils.equals(resultStatus, "8000")) {
                        Toast.makeText(mActivity, "支付結(jié)果確認(rèn)中", Toast.LENGTH_SHORT).show();
                    } else if (TextUtils.equals(resultStatus, "6001")) {
                        mPayCallBack.onResponse(-2);
                    } else {
                        // 其他值就可以判斷為支付失敗装诡,包括用戶主動(dòng)取消支付银受,或者系統(tǒng)返回的錯(cuò)誤
                        mPayCallBack.onResponse(-1);
                    }
                }
                break;
            }
            case AliPayWay.SDK_CHECK_FLAG: {
                Toast.makeText(BaseApplication.getContext(), "檢查結(jié)果為:" + msg.obj, Toast.LENGTH_SHORT).show();
                break;
            }
            default:
                break;
        }
    }
};
/**
 * sign the order info. 對(duì)訂單信息進(jìn)行簽名
 *
 * @param content 待簽名訂單信息
 */
public String sign(String content) {
    return SignUtils.sign(content, RSA_PRIVATE);
}
/**
 * get the sign type we use. 獲取簽名方式
 */
public String getSignType() {
    return "sign_type=\"RSA\"";
}
@Override
public void startPay(Activity activity, AliPayBean aliPayBean, PayCallBack payCallback) {
    this.mActivity = activity;
    this.mPayCallBack = payCallback;
    String orderInfo = aliPayBean.getData().getSign_string();
    String sign = aliPayBean.getData().getSign();
    try {
        // 僅需對(duì)sign 做URL編碼
        sign = URLEncoder.encode(sign, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    // 完整的符合支付寶參數(shù)規(guī)范的訂單信息
    final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
    Log.d("payInfo------->", payInfo);
    Runnable payRunnable = new Runnable() {
        @Override
        public void run() {
            // 構(gòu)造PayTask 對(duì)象
            PayTask alipay = new PayTask(mActivity);
            // 調(diào)用支付接口践盼,獲取支付結(jié)果
            String result = alipay.pay(payInfo, true);
            Message msg = new Message();
            msg.what = AliPayWay.SDK_PAY_FLAG;
            msg.obj = result;
            mHandler.sendMessage(msg);
        }
    };
    // 必須異步調(diào)用
    Thread payThread = new Thread(payRunnable);
    payThread.start();
}
}

微信支付對(duì)象

public class WeChatWay implements BasePayWay{
    private static WeChatWay mWeChatPay;
    private IWXAPI api;
    private Context mContext;
    private PayCallBack mPayCallBack;
    private static final int TIMELINE_SUPPORTED_VERSION = 0x21020001;
    private WeChatWay(String wxAppId) {
        api = WXAPIFactory.createWXAPI(mContext, null);
        api.registerApp(wxAppId);
    }
    public static WeChatWay getInstance(String wxAppId) {
        if (mWeChatPay == null) {
            synchronized (WeChatWay.class) {
                if (mWeChatPay == null) {
                    mWeChatPay = new WeChatWay(wxAppId);
                }
            }
        }
        return mWeChatPay;
    }
    public IWXAPI getApi() {
        return api;
    }
    private boolean checkWeChatPay() {
        int wxSdkVersion = api.getWXAppSupportAPI();
        boolean isWeChatAble = true;
        if (!api.isWXAppInstalled()) {
            CommonUtils.showToast(mContext, "使用微信支付必須先安裝微信客戶端");
            isWeChatAble = false;
        } else if (wxSdkVersion < TIMELINE_SUPPORTED_VERSION) {
            CommonUtils.showToast(mContext, "微信支付支持的最低版本高于當(dāng)前安裝版本,請先升級(jí)微信客戶端");
            isWeChatAble = false;
        }
        return isWeChatAble;
    }
    @Override
    public void startPay(Activity activity, WeChatBean weChatBean, PayCallBack payCallback) {
        mContext = activity.getApplicationContext();
        this.mPayCallBack = payCallback;
        if (checkWeChatPay()) {
            PayReq req = new PayReq();
            req.appId = weChatBean.getData().getAppid();
            req.partnerId = weChatBean.getData().getPartnerid();
            req.prepayId = weChatBean.getData().getPrepayid();
            req.packageValue = weChatBean.getData().getPackage_();
            req.nonceStr = weChatBean.getData().getNoncestr();
            req.timeStamp = weChatBean.getData().getTimestamp();
            req.sign = weChatBean.getData().getSign();
            Constant.PAY_FROM = 1;
            api.sendReq(req);
        } else {
            mPayCallBack.onResponse(-1);
        }
    }
    public void onResponse(int code) {
        mPayCallBack.onResponse(code);
    }
}

3.當(dāng)前頁面回調(diào)結(jié)果
使用接口統(tǒng)一回調(diào)宾巍;
定義接口

public interface PayCallBack {
// code: 0為失敗咕幻,-1為失敗,-2為取消
//通過code統(tǒng)一刷新界面
void onResponse(int code);
}

支付寶回調(diào)

switch (msg.what) {
                case AliPayWay.SDK_PAY_FLAG: {
                    PayResult payResult = new PayResult((String) msg.obj);
                    // 支付寶返回此次支付結(jié)果及加簽,建議對(duì)支付寶簽名信息拿簽約時(shí)支付寶提供的公鑰做驗(yàn)簽
                    String resultStatus = payResult.getResultStatus();
                    // 判斷resultStatus 為“9000”則代表支付成功顶霞,具體狀態(tài)碼代表含義可參考接口文檔
                    if (TextUtils.equals(resultStatus, "9000")) {
                        mPayCallBack.onResponse(0);
                    } else {
                        // 判斷resultStatus 為非“9000”則代表可能支付失敗
                        // “8000”代表支付結(jié)果因?yàn)橹Ц肚涝蚧蛘呦到y(tǒng)原因還在等待支付結(jié)果確認(rèn)肄程,最終交易是否成功以服務(wù)端異步通知為準(zhǔn)(小概率狀態(tài))
                        if (TextUtils.equals(resultStatus, "8000")) {
                            Toast.makeText(mActivity, "支付結(jié)果確認(rèn)中", Toast.LENGTH_SHORT).show();
                        } else if (TextUtils.equals(resultStatus, "6001")) {
                            mPayCallBack.onResponse(-2);
                        } else {
                            // 其他值就可以判斷為支付失敗,包括用戶主動(dòng)取消支付选浑,或者系統(tǒng)返回的錯(cuò)誤
                            mPayCallBack.onResponse(-1);
                        }
                    }
                    break;
                }
                case AliPayWay.SDK_CHECK_FLAG: {                    Toast.makeText(BaseApplication.getContext(), "檢查結(jié)果為:" + msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                }
                default:
                    break;
            }

微信回調(diào):
微信需要在WXPayEntryActivity單獨(dú)做一些處理蓝厌。

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);    
      WeChatWay.getInstance(Constant.APP_ID).getApi().handleIntent(getIntent(),this);
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
       WeChatWay.getInstance(Constant.APP_ID).getApi().handleIntent(intent, this);
    }
    @Override
    public void onReq(BaseReq req) {
    }
    /**
     * 四、接收支付返回結(jié)果
     */
    @Override
    public void onResp(BaseResp resp) {
        WeChatWay.getInstance(Constant.APP_ID).onResponse(resp.errCode);
    }
}

使用方法

將服務(wù)端返回的數(shù)據(jù)解析成預(yù)先定義好的AlipayBean,然后調(diào)起支付古徒。

▍支付寶

RxSubscriber rxSubscriber = new RxSubscriber(this, new Callback() {
                        @Override
                        public void onNext(WeChatBean weChatBean) {
                            if (weChatBean.getCode().equals("waitpay")) {
                                //調(diào)起微信支付
                                WeChatWay weChatWay = WeChatWay.getInstance(Constant.APP_ID);                                
                                                weChatWay.startPay(OrderDetailActivity.this, 
                                                weChatBean, new PayCallBack() {
                                    @Override
                                    public void onResponse(int code) {
                                        refreshDataWithCode(code);
                                    }
                                });
                            } else {
                                CommonUtils.showToast(mContext, weChatBean.getMessage());
                            }
                        }
                    });                 RequestManager.getInstance().sendRequest(weChatBeanObservable, rxSubscriber);

▍微信

ObservableweChatBeanObservable = RxRequest.getInstance().getProxy(false).callWeChatPay(map);
                    RxSubscriber rxSubscriber = new RxSubscriber(this, new Callback() {
                        @Override
                        public void onNext(WeChatBean weChatBean) {
                            if (weChatBean.getCode().equals("waitpay")) {
                                //調(diào)起微信支付
                                WeChatWay weChatWay = WeChatWay.getInstance(Constant.APP_ID);
                                weChatWay.startPay(OrderDetailActivity.this, weChatBean, new PayCallBack() {
                                    @Override
                                    public void onResponse(int code) {
                                        refreshDataWithCode(code);
                                    }
                                });
                            } else {
                                CommonUtils.showToast(mContext, weChatBean.getMessage());
                            }
                        }
                    });
                    RequestManager.getInstance().sendRequest(weChatBeanObservable, rxSubscriber);

其他

▍demo地址

https://github.com/wustor/PayDemo

▍參考文章

EasyPay(易支付)拓提,兩分鐘集成三種Android支付方式
http://www.reibang.com/p/bd4d44c33532#

▍作者:wustor,http://www.reibang.com/p/53359f844cfa

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末隧膘,一起剝皮案震驚了整個(gè)濱河市代态,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疹吃,老刑警劉巖蹦疑,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異萨驶,居然都是意外死亡歉摧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門篡撵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來判莉,“玉大人,你說我怎么就攤上這事育谬∪眩” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵膛檀,是天一觀的道長锰镀。 經(jīng)常有香客問我,道長咖刃,這世上最難降的妖魔是什么泳炉? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮嚎杨,結(jié)果婚禮上花鹅,老公的妹妹穿的比我還像新娘。我一直安慰自己枫浙,他們只是感情好刨肃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布古拴。 她就那樣靜靜地躺著,像睡著了一般真友。 火紅的嫁衣襯著肌膚如雪黄痪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天盔然,我揣著相機(jī)與錄音桅打,去河邊找鬼。 笑死愈案,一個(gè)胖子當(dāng)著我的面吹牛挺尾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刻帚,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼潦嘶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了崇众?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤航厚,失蹤者是張志新(化名)和其女友劉穎顷歌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幔睬,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眯漩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了麻顶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赦抖。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辅肾,靈堂內(nèi)的尸體忽然破棺而出队萤,到底是詐尸還是另有隱情,我是刑警寧澤矫钓,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布要尔,位于F島的核電站,受9級(jí)特大地震影響新娜,放射性物質(zhì)發(fā)生泄漏赵辕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一概龄、第九天 我趴在偏房一處隱蔽的房頂上張望还惠。 院中可真熱鬧,春花似錦私杜、人聲如沸蚕键。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嚎幸。三九已至颜矿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嫉晶,已是汗流浹背骑疆。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留替废,地道東北人箍铭。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像椎镣,于是被迫代替她去往敵國和親诈火。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容

  • 支付寶簡介文檔 (適用于ydm-java接口與后臺(tái),如有誤入惊科,但愿也能給您帶來幫助) 此文檔寫于2017年3月拍摇,只...
    隔壁付叔叔閱讀 17,077評(píng)論 3 19
  • 一、背景介紹 作為一名Android開發(fā)馆截,從最初的跌跌撞撞到現(xiàn)在小有所悟充活,這其中經(jīng)歷過的辛酸苦辣也是一種痛并快樂著...
    freecats08閱讀 4,845評(píng)論 7 54
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,193評(píng)論 25 707
  • 實(shí)現(xiàn)支付寶支付的準(zhǔn)備工作: 1.向支付寶簽約,成為支付寶的商戶 簽約完成后蜡娶,支付寶會(huì)提供一些必要的數(shù)據(jù)給我們 商戶...
    Anson楊春安閱讀 8,208評(píng)論 0 6
  • 無意間在今天晚上看到了駭客任務(wù)混卵,重新了解一次屬於它的世界觀,雖然有很多解釋窖张,都很有道理 但節(jié)錄其中最喜歡的幾段話"...
    小魯閱讀 186評(píng)論 0 0