對(duì)接支付寶支付接口開(kāi)發(fā)筆記

支付寶對(duì)接學(xué)習(xí)筆記

功能介紹:

  • 支付寶對(duì)接
  • 支付寶回調(diào)
  • 查詢支付狀態(tài)(略過(guò)不講)

要求:

  • 熟悉支付寶對(duì)接核心文檔井厌,調(diào)通支付寶官方Demo
  • 解析支付寶SDK對(duì)接源碼
  • RSA1和RSA2驗(yàn)證簽名及加解密
  • 避免支付寶的重復(fù)通知而加數(shù)據(jù)校驗(yàn)(略)

技巧:

  • ngrok 外網(wǎng)穿透
  • 生成二維碼并持久化到圖片服務(wù)器

調(diào)試完demo后,集合到開(kāi)發(fā)項(xiàng)目。
把支付寶依賴的jar寶按照提供版本要求導(dǎo)入寻馏,sdk則放在web下lib文件夾下。然后在module的依賴中導(dǎo)入lib下的本地jar包(坑V壮啊滑燃!不然會(huì)報(bào)紅)
那么為什么不統(tǒng)一使用pom導(dǎo)入呢往果?原因就是阿里沒(méi)有提供該jar包的線上導(dǎo)入疆液,只能本地導(dǎo)入。為了統(tǒng)一jar地址陕贮,所以必須先配置sdk的jar包的位置堕油。(在這之前還要配置一個(gè)maven插件以加載本地jar包).

接下來(lái)簡(jiǎn)單梳理一遍流程:

一、登錄進(jìn)入螞蟻金服

本次使用沙箱環(huán)境下進(jìn)行整合肮之,沙箱環(huán)境開(kāi)發(fā)上線流程差別不大馍迄,和正式幾乎是一致的,只是切換不同的APPID和支付寶網(wǎng)關(guān)局骤。


image.png

二、下載官方的demo

這里選中java版的demo


image.png

選中idea導(dǎo)入暴凑。先在本地調(diào)通再集成到系統(tǒng)中去峦甩。


image.png

右鍵運(yùn)行主函數(shù)會(huì)發(fā)現(xiàn)運(yùn)行不了,那是因?yàn)槲覀冞€沒(méi)有修改配置文件中設(shè)置现喳。

對(duì)應(yīng)配置如下凯傲。


image.png

那么問(wèn)題來(lái)了怎么生成這些公鑰私鑰呢?前往這里根據(jù)系統(tǒng)下載對(duì)應(yīng)的工具嗦篱。

image.png

接著:

image.png

配置好配置文件后冰单,運(yùn)行一下:
image.png

運(yùn)行沒(méi)有問(wèn)題,證明已經(jīng)調(diào)通灸促。下載沙箱版的支付寶诫欠,登錄沙箱提供的買(mǎi)家賬戶,復(fù)制當(dāng)面付二維碼找一個(gè)二維碼生成工具掃描支付看能不能成功浴栽。
image.png

掃描支付后:


image.png

到此為止本地支付寶已經(jīng)調(diào)通荒叼,這個(gè)還是相對(duì)來(lái)說(shuō)比較簡(jiǎn)單的。從demo的項(xiàng)目結(jié)構(gòu)來(lái)看典鸡,這是一個(gè)web項(xiàng)目被廓,可以自行配置運(yùn)行環(huán)境再運(yùn)行,測(cè)試會(huì)更加方便一點(diǎn)萝玷,如果沒(méi)有出錯(cuò)的話就會(huì)出現(xiàn)下圖:


image.png

image.png

三嫁乘、系統(tǒng)對(duì)接支付寶支付接口

雖然官網(wǎng)已經(jīng)寫(xiě)得很清楚了,但是第一次對(duì)接還是很吃力球碉,這里寫(xiě)一下思路:

1蜓斧、先把demo中的aplipay那個(gè)包及配置文件復(fù)制放到需要集成項(xiàng)目的類路徑下:
image.png
2、把支付寶依賴的jar寶按照提供版本要求導(dǎo)入汁尺,sdk則放在web下lib文件夾下法精。然后在module的依賴中導(dǎo)入lib下的本地jar包(坑!!不然會(huì)報(bào)紅)

那么為什么不統(tǒng)一使用pom導(dǎo)入呢搂蜓?原因就是阿里沒(méi)有提供該jar包的線上導(dǎo)入狼荞,只能本地導(dǎo)入。為了統(tǒng)一jar地址帮碰,所以必須先配置sdk的jar包的位置相味。


image.png

image.png

還要配置一個(gè)maven插件以加載本地jar包.


image.png
3、運(yùn)行下主函數(shù)沒(méi)有報(bào)錯(cuò)就是初步導(dǎo)入成功殉挽。
image.png

四丰涉、對(duì)接支付寶支付接口

1、這里是整個(gè)過(guò)程中最難的部分斯碌。

從下訂單到支付到支付完成一死,省去下訂單的接口,支付過(guò)程需要用到兩個(gè)接口傻唾,一個(gè)是支付接口投慈,一個(gè)是給支付寶授權(quán)回調(diào)接口。訂單這里采用模擬數(shù)據(jù)冠骄。

2伪煤、首先支付接口

掃碼支付調(diào)用流程:

image.png

官方文檔參數(shù)描述:


image.png

因此先查詢數(shù)據(jù)組裝支付寶要求的參數(shù)值:

Map<String, String> resultMap = Maps.newHashMap();
        Order order = orderMapper.selectByUserAndOrderNo(userId, orderNo);
        if (order == null) {
            return ServerRespond.createByErrorMessage("用戶沒(méi)有該訂單");

        }
        resultMap.put("orderNo", String.valueOf(order.getOrderNo()));

        // (必填) 商戶網(wǎng)站訂單系統(tǒng)中唯一訂單號(hào),64個(gè)字符以內(nèi)凛辣,只能包含字母抱既、數(shù)字、下劃線扁誓,
        // 需保證商戶系統(tǒng)端不能重復(fù)防泵,建議通過(guò)數(shù)據(jù)庫(kù)sequence生成,
        String outTradeNo = order.getOrderNo().toString();

        // (必填) 訂單標(biāo)題跋理,粗略描述用戶的支付目的择克。如“xxx品牌xxx門(mén)店當(dāng)面付掃碼消費(fèi)”
        String subject = new StringBuilder().append("寸金在線商城,訂單號(hào):").append(outTradeNo).toString();

        // (必填) 訂單總金額前普,單位為元肚邢,不能超過(guò)1億元
        // 如果同時(shí)傳入了【打折金額】,【不可打折金額】,【訂單總金額】三者,則必須滿足如下條件:【訂單總金額】=【打折金額】+【不可打折金額】
        String totalAmount = order.getPayment().toString();

        // (可選) 訂單不可打折金額,可以配合商家平臺(tái)配置折扣活動(dòng)拭卿,如果酒水不參與打折骡湖,則將對(duì)應(yīng)金額填寫(xiě)至此字段
        // 如果該值未傳入,但傳入了【訂單總金額】,【打折金額】,則該值默認(rèn)為【訂單總金額】-【打折金額】
        String undiscountableAmount = "0";

        // 賣(mài)家支付寶賬號(hào)ID,用于支持一個(gè)簽約賬號(hào)下支持打款到不同的收款賬號(hào)峻厚,(打款到sellerId對(duì)應(yīng)的支付寶賬號(hào))
        // 如果該字段為空响蕴,則默認(rèn)為與支付寶簽約的商戶的PID,也就是appid對(duì)應(yīng)的PID
        String sellerId = "";

        // 訂單描述惠桃,可以對(duì)交易或商品進(jìn)行一個(gè)詳細(xì)地描述浦夷,比如填寫(xiě)"購(gòu)買(mǎi)商品2件共15.00元"
        String body = new StringBuilder().append("訂單").append(outTradeNo).append("購(gòu)買(mǎi)商品共").append(totalAmount).append("元").toString();

        // 商戶操作員編號(hào)辖试,添加此參數(shù)可以為商戶操作員做銷售統(tǒng)計(jì)
        String operatorId = "test_operator_id";

        // (必填) 商戶門(mén)店編號(hào),通過(guò)門(mén)店號(hào)和商家后臺(tái)可以配置精準(zhǔn)到門(mén)店的折扣信息劈狐,詳詢支付寶技術(shù)支持
        String storeId = "test_store_id";

        // 業(yè)務(wù)擴(kuò)展參數(shù)罐孝,目前可添加由支付寶分配的系統(tǒng)商編號(hào)(通過(guò)setSysServiceProviderId方法),詳情請(qǐng)咨詢支付寶技術(shù)支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088100200300400500");

        // 支付超時(shí)肥缔,定義為120分鐘
        String timeoutExpress = "120m";

        // 商品明細(xì)列表莲兢,需填寫(xiě)購(gòu)買(mǎi)商品詳細(xì)信息,
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();

        List<OrderItem> orderItemList = orderItemMapper.getByOrderNoUserId(orderNo, userId);
        System.out.println(orderItemList.get(0));
        for (OrderItem orderItem : orderItemList) {

            GoodsDetail goods = GoodsDetail.newInstance(orderItem.getProductId().toString(), orderItem.getProductName().toString(),

                    BigDecimalUtil.mul(orderItem.getCurrentUnitPrice().doubleValue(), new Double(100).doubleValue()).longValue(), orderItem.getQuantity());
            goodsDetailList.add(goods);
        }

//        // 創(chuàng)建一個(gè)商品信息续膳,參數(shù)含義分別為商品id(使用國(guó)標(biāo))改艇、名稱、單價(jià)(單位為分)坟岔、數(shù)量谒兄,如果需要添加商品類別,詳見(jiàn)GoodsDetail
//        GoodsDetail goods1 = GoodsDetail.newInstance("goods_id001", "xxx小面包", 1000, 1);
//        // 創(chuàng)建好一個(gè)商品后添加至商品明細(xì)列表
//        goodsDetailList.add(goods1);
//
//        // 繼續(xù)創(chuàng)建并添加第一條商品信息社付,用戶購(gòu)買(mǎi)的產(chǎn)品為“黑人牙刷”舵变,單價(jià)為5.00元,購(gòu)買(mǎi)了兩件
//        GoodsDetail goods2 = GoodsDetail.newInstance("goods_id002", "xxx牙刷", 500, 2);
//        goodsDetailList.add(goods2);

        // 創(chuàng)建掃碼支付請(qǐng)求builder瘦穆,設(shè)置請(qǐng)求參數(shù)
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo)
                .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
                .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
                .setTimeoutExpress(timeoutExpress)

                .setNotifyUrl(PropertiesUtil.getProperty("alipay.callback.url"))//支付寶服務(wù)器主動(dòng)通知商戶服務(wù)器里指定的頁(yè)面http路徑,根據(jù)需要設(shè)置
                .setGoodsDetailList(goodsDetailList);
        /** 一定要在創(chuàng)建AlipayTradeService之前調(diào)用Configs.init()設(shè)置默認(rèn)參數(shù)
         *  Configs會(huì)讀取classpath下的zfbinfo.properties文件配置信息,如果找不到該文件則確認(rèn)該文件是否在classpath目錄
         */
        Configs.init("zfbinfo.properties");

        /** 使用Configs提供的默認(rèn)參數(shù)
         *  AlipayTradeService可以使用單例或者為靜態(tài)成員對(duì)象赊豌,不需要反復(fù)new
         */
        AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();

        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);

接著就是出參扛或,二維碼的生成,并展示給用戶支付碘饼。圖片展示通過(guò)上傳到圖片服務(wù)器的方式熙兔。所以前提得已經(jīng)有一個(gè)ftp服務(wù)器和連接服務(wù)器的ftp工具類。

switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付寶預(yù)下單成功: )");

                AlipayTradePrecreateResponse response = result.getResponse();
                dumpResponse(response);

//                關(guān)鍵部分艾恼,把生成二維碼上傳到圖片服務(wù)器
                File folder = new File(path);
                if (!folder.exists()) {

                    folder.setWritable(true);
                    folder.mkdirs();
                }

                // 需要修改為運(yùn)行機(jī)器上的路徑
                //替換s占位符
                String QRPath = String.format(path + "/qr-%s.png",
                        response.getOutTradeNo());
                String qrFileName = String.format("qr-%s.png", response.getOutTradeNo());
                //支付寶調(diào)用guava生成二維碼
                ZxingUtils.getQRCodeImge(response.getQrCode(), 256, QRPath);

                File targetFile = new File(path, qrFileName);
                try {
                    FTPUtil.uploadFile(Lists.newArrayList(targetFile));
                } catch (IOException e) {
                    log.error("上傳二維碼異常", e);
                }
                log.info("QRPath:" + QRPath);
                String qrUrl = PropertiesUtil.getProperty("ftp.server.http.prefix") + targetFile.getName();
                resultMap.put("qrUrl", qrUrl);

                return ServerRespond.createBySuccess(resultMap);

            case FAILED:
                log.error("支付寶預(yù)下單失敗!!!");
                return ServerRespond.createByErrorMessage("支付寶預(yù)下單失敗");

            case UNKNOWN:
                log.error("系統(tǒng)異常住涉,預(yù)下單狀態(tài)未知!!!");
                return ServerRespond.createByErrorMessage("系統(tǒng)異常,預(yù)下單狀態(tài)未知!!!");
            default:
                log.error("不支持的交易狀態(tài)钠绍,交易返回異常!!!");
                return ServerRespond.createByErrorMessage("不支持的交易狀態(tài)舆声,交易返回異常!!!");
        }

3、支付寶回調(diào)接口

這個(gè)授權(quán)支付寶調(diào)用的接口柳爽,所以不能是本地ip媳握,必須得有一個(gè)外網(wǎng)ip,最直接的方式是服務(wù)器上操作磷脯,但顯然現(xiàn)在是沒(méi)辦法這樣做的蛾找,于是采用了內(nèi)網(wǎng)穿透的辦法,內(nèi)網(wǎng)穿透工具我采用ngrok赵誓,缺點(diǎn)是不能綁定固定域名打毛。


image.png

授權(quán)回調(diào)接口:

public ServerRespond aliCallback(Map<String, String> params) {
    //處理回調(diào)數(shù)據(jù)
        Long orderNo = Long.parseLong(params.get("out_trade_no"));
        String tradeNo = params.get("trade_no");
        String tradeStatus = params.get("trade_status");
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            return ServerRespond.createByErrorMessage("寸金商場(chǎng)訂單柿赊,回調(diào)忽略");
        }
        if (order.getStatus() >= Const.OrderStatus.PAID.getCode()) {
            return ServerRespond.createBySuccess("支付寶重復(fù)調(diào)用");
        }
        if (Const.alipayCallback.TRADE_STATUS_TRADE_SUCCESS.equals(tradeStatus)) {
            order.setPaymentTime(DateTimeUtil.strToDate(params.get("gmt_payment")));
            order.setStatus(Const.OrderStatus.PAID.getCode());
            orderMapper.updateByPrimaryKeySelective(order);
        }
        PayInfo payInfo = new PayInfo();
        payInfo.setUserId(order.getUserId());
        payInfo.setOrderNo(order.getOrderNo());
        payInfo.setPayPlatform(Const.PayPlatFormEnum.ALIPAY.getCode());
        payInfo.setPlatformNumber(tradeNo);
        payInfo.setPlatformStatus(tradeStatus);
        payInfoMapper.insert(payInfo);
        return ServerRespond.createBySuccess();
    }

關(guān)于回調(diào)接口可以看看文檔

image.png

第一步: 在通知返回參數(shù)列表中幻枉,除去sign碰声、sign_type兩個(gè)參數(shù)外,凡是通知返回回來(lái)的參數(shù)皆是待驗(yàn)簽的參數(shù)展辞。

這一步很重要奥邮,不然沒(méi)辦法驗(yàn)簽,看源碼,便可知sdk已經(jīng)做了罗珍,接著組裝StringBuffer洽腺,因?yàn)镾tringBuffer是線程安全的,可以以應(yīng)付高并發(fā)操作覆旱。


image.png

第三步: 將簽名參數(shù)(sign)使用base64解碼為字節(jié)碼串蘸朋。

這一步sdk也做了。


image.png

第四步: 使用RSA的驗(yàn)簽方法扣唱,通過(guò)簽名字符串藕坯、簽名參數(shù)(經(jīng)過(guò)base64解碼)及支付寶公鑰驗(yàn)證簽名。

然而需要注意的是上面這個(gè)方法實(shí)際上是不ok的噪沙,因?yàn)樗乃惴ㄕ?qǐng)求類型跟配置中的不一致炼彪。我們的請(qǐng)求算法類型是RSA2不是SHA1WithRSA。


image.png

然而還有一個(gè)函數(shù)重載允許多了一個(gè)可以選擇加密類型的參數(shù)正歼。


image.png

點(diǎn)擊rsaCheck辐马,當(dāng)signType的值equal不同的值調(diào)用不同的方法,很明顯第二個(gè)就是我們要的局义。
image.png

于是在控制器中就得這樣寫(xiě):


image.png

五喜爷、對(duì)接測(cè)試

完成接口編寫(xiě)后就是接口測(cè)試

從數(shù)據(jù)庫(kù)中提一個(gè)未付款的訂單號(hào)做測(cè)試

image.png

成功的話會(huì)返回一個(gè)付款二維碼
image.png

打開(kāi)該二維碼:
image.png

如圖則已經(jīng)對(duì)接成功:
image.png

以上就是支付寶集成的主要過(guò)程,代碼只是貼了一部分具體可以看這里萄唇。

六檩帐、總結(jié)

雖然官方的說(shuō)明已經(jīng)夠詳細(xì)了,但是真正入手去做還是有很多坑另萤,此次對(duì)接過(guò)程中學(xué)習(xí)很多湃密,其中尤其要注意的是因?yàn)楣俜降年P(guān)系,sdk必須放在lib下四敞,為了打包時(shí)能夠同其他依賴包一起打包勾缭,還需配置好對(duì)sdk的打包插件,其他支付寶需要的依賴包如果用maven引入的話盡量保持版本一致或者一起跟支付寶sdk一同從Demo中復(fù)制過(guò)來(lái)放在lib包下目养。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俩由,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子癌蚁,更是在濱河造成了極大的恐慌幻梯,老刑警劉巖兜畸,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異碘梢,居然都是意外死亡咬摇,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)煞躬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肛鹏,“玉大人,你說(shuō)我怎么就攤上這事恩沛≡谌牛” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵雷客,是天一觀的道長(zhǎng)芒珠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)搅裙,這世上最難降的妖魔是什么皱卓? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮部逮,結(jié)果婚禮上娜汁,老公的妹妹穿的比我還像新娘。我一直安慰自己兄朋,他們只是感情好存炮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蜈漓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宫盔。 梳的紋絲不亂的頭發(fā)上融虽,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音灼芭,去河邊找鬼有额。 笑死,一個(gè)胖子當(dāng)著我的面吹牛彼绷,可吹牛的內(nèi)容都是我干的巍佑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼寄悯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼萤衰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起猜旬,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤脆栋,失蹤者是張志新(化名)和其女友劉穎倦卖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體椿争,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怕膛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秦踪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褐捻。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖椅邓,靈堂內(nèi)的尸體忽然破棺而出柠逞,到底是詐尸還是另有隱情,我是刑警寧澤希坚,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布边苹,位于F島的核電站,受9級(jí)特大地震影響裁僧,放射性物質(zhì)發(fā)生泄漏个束。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一聊疲、第九天 我趴在偏房一處隱蔽的房頂上張望茬底。 院中可真熱鬧,春花似錦获洲、人聲如沸阱表。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)最爬。三九已至,卻和暖如春门岔,著一層夾襖步出監(jiān)牢的瞬間爱致,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工寒随, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糠悯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓妻往,卻偏偏與公主長(zhǎng)得像互艾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子讯泣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評(píng)論 25 707
  • 用兩張圖告訴你纫普,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,693評(píng)論 2 59
  • 1好渠、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明先生_x閱讀 15,968評(píng)論 3 119
  • 成圖: 最近畫(huà)黑白畫(huà)比較多局嘁,于是乎我就顛顛的下載了掃描全能王~黑白畫(huà)掃描效果爆棚呀~然而帶顏色的真——一言難盡溉箕! ...
    悅離閱讀 1,197評(píng)論 0 5
  • 五絕·客雅竹新 文/青山野渡 香徑向幽村,柴扉系...
    青山野渡閱讀 493評(píng)論 6 8