android google play接入一样的操作借用了网上别人博客的部分 改正的一些错误,主要介绍 cocos2d-x google play 接入不一样的部分

如果没有GooglePlay此处附上安装Google Play的一键安装器的链接(需要Root权限):http://www.muzhiwan.com/com.muzhiwan.gsfinstaller-86095.html

  之前用过Google BillingV2,感觉不太爽。V2版支付走的是异步通知,不能即时得到支付结果,支付、查询接口太过复杂,还有就是没找到RestoreOrder接口,因此选择使用V3版,网上大部分都是介绍GoogleBilling的付费机制原理,具体针对某个功能点的很模糊,所以如果大家想了解GoogleBilling付费机制的这篇博文大可不看,网上转载多的是,我写这篇博文的目的是想让大家快速的将Google支付集成到自己项目中。
  集成Google in-appBilling的前提是你已经正确连接上VPN(大陆用户),基本上每个公司都会有VPN的,这个找项目组长去要。
也正式由于天朝的封锁使得在大陆接Google的支付加大了难度。所以要想接in-appBilling首先要有一个稳定的vpn,PS:非大陆的就行,最好是美、日的。
VPN设置:

注意:类型根据VPN而定,我用的是L2TP/IPSecPSK,选择此类型时,编辑只需填写名称,服务器地址和IPSec预共享密钥即可,然后连接的时候填写帐号和密码。当打开Google商店能看到付费软件表名VPN已成功连接,如果显示VPN已连接但还看不到付费软件时,进入应用程序管理器分别清除GooglePlay服务和Google Play商店数据之后再打开Google商店即可。

文档下载链接为:  http://pan.baidu.com/share/link?shareid=1387554851&uk=473193131
源码下载链接为:http://pan.baidu.com/share/link?shareid=1579953623&uk=473193131
  注:源码导入工程是不可用的,需将包名、版本号、版本code、签名改为你上传至Google控制台测试应用的包名、版本号、版本code、签名,且将MainActivity.java中的Stringbase64EncodedPublicKey ="";填写上你应用程序的签名。PS:签名即Eclipse->AndroidTools->Export Signed Application Package...
  网盘分享中的DemoForGoogleBilling.apk文件是可支付的,但支付会将钱打到我们公司账户上,因为我用的是上线app的key。
一:接入流程:
  1.申请Google开发者帐号,开发人员控制台左侧选择“设置”填写测试人员帐号。
  2.添加新应用,此处有个“上传APK”,此处上传的apk上传到Bate版或者ALPHA版,但包名、版本code、版本name、签名需跟最终上线的产品保持一致。此处上传测试版本的目的是当你支付接入完毕后测试时用。
  3.集成Google Billing。
    (1).Purchasing Items,购买商品时的通信过程

    (2).Consuming In-app Products,消耗产品时的通信过程
  4.测试支付。
    (1).测试支付官方文档链接http://developer.android.com/google/play/billing/billing_testing.html
    (2).Testing with staticresponses,静态测试,即当支付状态为一下四种情况时游戏逻辑是否正确。
官方给出的4种如下:
There are four reserved product IDs for testing static In-appBilling responses:
android.test.purchased
When you make an In-app Billing request with this product ID,Google Play responds as though you successfully purchased an item.The response includes a JSON string, which contains fake purchaseinformation (for example, a fake order ID). In some cases, the JSONstring is signed and the response includes the signature so you cantest your signature verification implementation using theseresponses.
android.test.canceled
When you make an In-app Billing request with this product IDGoogle Play responds as though the purchase was canceled. This canoccur when an error is encountered in the order process, such as aninvalid credit card, or when you cancel a user's order before it ischarged.
android.test.refunded
When you make an In-app Billing request with this product ID,Google Play responds as though the purchase was refunded. Refundscannot be initiated through Google Play's in-app billing service.Refunds must be initiated by you (the merchant). After you processa refund request through your Google Wallet merchant account, arefund message is sent to your application by Google Play. Thisoccurs only when Google Play gets notification from Google Walletthat a refund has been made. For more information about refunds,see Handling IN_APP_NOTIFY messages and In-app BillingPricing.
android.test.item_unavailable
When you make an In-app Billing request with this product ID,Google Play responds as though the item being purchased was notlisted in your application's product list.
    例:当配置为android.test.purchased时:
[java] view plaincopyprint?
  1. mHelper.launchPurchaseFlow(MainActivity.this,“android.test.purchased”,RC_REQUEST,mPurchaseFinishedListener);
mHelper.launchPurchaseFlow(MainActivity.this,“android.test.purchased”,RC_REQUEST,mPurchaseFinishedListener);

    (3).当游戏逻辑测试通过后,进行支付测试。测试时手机设备上绑定的Google帐号必须是在开发者控制台中配置的测试帐号,绑定非大陆的信用卡,支付后会在开发者控制台看到支付的订单,由于是测试订单,可以将测试产生的费用返还给绑定的信用卡。
    测试效果图如下(由于本人没有非大陆的信用卡,所以只能看到这个界面,上线项目“蘑菇帮”测试ok)

支付接入过程中涉及到的接口及名词:

一:受管理商品和不受管理商品

  1.受管理商品即不可重复购买的,例如:解锁关卡,激活游戏等。
  2.不受管理商品即可重复购买的,例如:购买金币,购买药水,等消耗品。
  3.订阅商品,由于项目中没有涉及到,如有需要的可以翻阅一下Google Billing文档。
Google in-app BillingV3将所有商品默认为受管理的,如果有不受管理商品则需要调用consumeAsync去消耗调,(或者你可以通俗的理解为,当你成功购买一个道具,Google后台会将此道具加上标记,当你调用consumeAsync将订单消耗掉时,该订单标记被取消)。
二:三个回调

1.IabHelper.OnIabPurchaseFinishedListener支付完成的回调,如果是受管理的商品在此回调中直接可以将道具给用户

2.IabHelper.OnConsumeFinishedListener消耗完成的回调,当不受管理的商品被成功消耗进入此回调,此时将不受管理的商品给用户

3.IabHelper.QueryInventoryFinishedListener查询完成的回调,RestoreOrder的时候用,当有订单成功付款但由于种种原因(突然断网、断电等)没收到Google支付成功的回调时,在这里可以查询到此订单,此时需要对订单进行处理(给用户道具等)。

四:测试用的app一定要跟上传到Google的测试版的包名、版本code、name、签名一致,否则无法进行支付测试。

1.当签名不一致或者版本code、版本name不一致时错误界面如下:

2.当包名不一致时错误界面如下:

接下来跟大家一起看一下代码具体实现:
1.下载in-app-billing-v03,下载地址:http://pan.baidu.com/share/link?shareid=1387554851&uk=473193131将下载后的压缩包解压:


将src目录下两个包及包中的java文件引入工程,例如:

2.添加权限:
[html] view plaincopyprint?
  1. <uses-permission android:name="com.android.vending.BILLING" />
<uses-permissionandroid:name="com.android.vending.BILLING"/>
3.添加支付代码:
   初始化IapHelper:
[java] view plaincopyprint?
  1. String base64EncodedPublicKey ="";此处填写Google控制台添加新应用程序后的appid
  2. mHelper = new IabHelper(this, base64PublicKey);
  3. mHelper.enableDebugLogging(true);
  4. Log.d(TAG, "Starting setup.");
  5. System.out.println("#######################################");
  6. mHelper.startSetup(new OnIabSetupFinishedListener() {
  7. @Override
  8. public void onIabSetupFinished(IabResult result) {
  9. // TODO Auto-generated method stub
  10. Log.d(TAG,"setupfinish.");
  11. if(!result.isSuccess()){
  12. System.out.println("连接遇到问题"+result);
  13. return;
  14. }
  15. System.out.println("连接成功");
  16. iap_is_ok = true;
  17. mHelper.queryInventoryAsync(mGotInventoryListener);//回调未处理的订单
  18. }
  19. });
String base64EncodedPublicKey ="";此处填写Google控制台添加新应用程序后的appidmHelper =new IabHelper(this, base64EncodedPublicKey);// enable debuglogging (for a production application, you should set this tofalse).mHelper.enableDebugLogging(false);// Start setup. This is asynchronous andthe specified listener// will be called oncesetup completes.Log.d(TAG,"Starting setup.");mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener(){publicvoid onIabSetupFinished(IabResult result){Log.d(TAG,"Setupfinished.");if (!result.isSuccess()) {// Ohnoes, there was a problem.complain("Problemsetting up in-app billing: " + result);return;}iap_is_ok = true;//Hooray, IAB is fully set up. Now, let's get an inventory of stuffwe own.Log.d(TAG, "Setup successful. Queryinginventory.");}});

调用支付接口:

[java] view plaincopyprint?
if (iap_is_ok){
   System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@"+str);
   mHelper.launchPurchaseFlow(this,这里是商品的id, 这里定义的请求id常量, mPurchaseFinishedListener);
  }else{
   System.out.println("连接失败");
   jniHelper.SendErro();//我在这里是回调cocos2d-x中的c++代码
  } 
if(iap_is_ok){
mHelper.launchPurchaseFlow(MainActivity.this,skus[1],RC_REQUEST, mPurchaseFinishedListener);
}else {
showMessage("提示", "GooglePlay初始化失败,当前无法进行支付,请确定您所在地区支持Google Play支付或重启游戏再试!");
}

在jiniHeler类中代码

public static native int SendErro();

c++中的实现代码处理这个错误

extern"C"
{
 void Java_org_cocos2dx_lua_jniHelper_SendErro(JNIEnv *env, jobject thiz)
 {
  CCLOG("CHENGONG");
  getErroToLua();
 }
};

调用查询接口:

[java] view plaincopyprint?
  1. mHelper.queryInventoryAsync(mGotInventoryListener);
mHelper.queryInventoryAsync(mGotInventoryListener);

调用获取道具价格接口:(因Google市场是根据不同国家显示不同货币价格,所以显示到游戏道具列表中的价格不是定值,而是动态获取的)

[java] view plaincopyprint?
billingservice =mHelper.getService();
Bundle querySkus = newBundle();querySkus.putStringArrayList("ITEM_ID_LIST", skus);
try {
Bundle skuDetails = billingservice.getSkuDetails(3,MainActivity.this.getPackageName(),"inapp", querySkus);
ArrayList<String> responseList =skuDetails.getStringArrayList("DETAILS_LIST");
if (null!=responseList) {
for (String thisResponse :responseList) {try {
SkuDetails d = newSkuDetails(thisResponse);for (int i = 0; i <sku_list.size(); i++) {
if(sku_list.get(i).equals(d.getSku())) {
price_list.set(i, d.getPrice());
}
}
iapHandler.sendEmptyMessage(0);}catch (JSONException e) {
// TODO Auto-generated catchblock
e.printStackTrace();
}}
}
}catch (RemoteException e) {
// TODO Auto-generated catchblock
e.printStackTrace();
}

public  void infoPrice(){
  
  new Thread(new Runnable() {//写一个线程防止阻塞主线程
   
   @Override
   public void run() {
    // TODO Auto-generated method stub
    ArrayList<String> skus = new ArrayList<String>();
    
    skus.add(DIAMOND_80);//这里的常量是我定义的商品id
    skus.add(DIAMOND_400);
    skus.add(DIAMOND_800);
    skus.add(DIAMOND_1600);
    skus.add(DIAMOND_4000);
    skus.add(DIAMOND_8000);
    billingservice = mHelper.getService();
    if (billingservice != null){//这里做空判断防止客户设备没有安装google play 导致空错误
     Bundle querySkus = new Bundle();
        querySkus.putStringArrayList("ITEM_ID_LIST", skus);
        System.out.println("##############"+querySkus.toString());
     try {
      Bundle skuDetails = billingservice.getSkuDetails(3, AppActivity.this.getPackageName(),"inapp", querySkus);
      ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
      if (null!=responseList) {
       pstr="";
       for (String thisResponse : responseList) {
                 try {
         SkuDetails d = new SkuDetails(thisResponse);

pstr = pstr + d.getPrice()+",";//将价格连接成一个字符创传进cocos2d-x中的c++中

} catch (JSONException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
                
             }
      }
     } catch (RemoteException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
    
   }
   
  }).start();
  mpstr = pstr ;//这里 mpstr是一个全局的静态变量 pstr是一个 全局变量 这样的赋值为了 后面再静态方法中返回这个价格的组合字符创到c++中
 }
 
 public static String getPrice(){
  return mpstr;//返回这个字符串
 }

c++部分代码实现

注意:加上平台预编译

std::string  OSHelper::getAPrice()
{
 std::string str = "nil";
 JniMethodInfo minfo;//定义Jni函数信息结构体

//getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数

bool isHave = JniHelper::getStaticMethodInfo(minfo,

"org/cocos2dx/lua/AppActivity",  //类的路径

"rtnActivity",   //方法名

"()Ljava/lang/Object;");   //括号里的是参数,后面的是返回值。

jobject activityObj;

if (isHave) {

activityObj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);

}

CCLog("正确获取到 jobj");
 //CCLog(jobj);
 JniMethodInfo methodInfo;
 isHave = JniHelper::getMethodInfo(methodInfo,

"org/cocos2dx/lua/AppActivity",  //类的路径

"infoPrice",   //方法名

"()V");   //括号里的是参数,后面的是返回值。

if (isHave) {
  CCLog("jni-javadddddd函数执行完毕");
  methodInfo.env->CallVoidMethod(activityObj, methodInfo.methodID);
  //CCLOG(str);
 }

CCLog("jni-java函数执行完毕");
 JniMethodInfo minfop;
 isHave = JniHelper::getStaticMethodInfo(minfop,

"org/cocos2dx/lua/AppActivity",  //类的路径

"getPrice",   //方法名

"()Ljava/lang/String;");   //括号里的是参数,后面的是返回值。

if (isHave) {

jstring jstr = (jstring)minfop.env->CallStaticObjectMethod(minfop.classID, minfop.methodID);
  str = JniHelper::jstring2string(jstr);
 }

return str;
}

三个回调:

[java] view plaincopyprint?
  1. // Callback for when a purchase is finished
  2. IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =newIabHelper.OnIabPurchaseFinishedListener() {
  3. publicvoidonIabPurchaseFinished(IabResult result, Purchase purchase) {
  4. Log.d(TAG,"Purchase finished: " + result+", purchase: " +purchase);
  5. if (result.isFailure()) {
  6. // Oh noes!
  7. complain("Error purchasing: " + result);
  8. return;
  9. }
  10. Log.d(TAG,"Purchase successful.");
  11. if(purchase.getSku().equals("coins_100")||purchase.getSku().equals("android.test.purchased")){
  12. mHelper.consumeAsync(purchase, mConsumeFinishedListener);
  13. }elseif (purchase.getSku().equals("double_income")) {
  14. //受管理的商品,开启双倍经验
  15. showMessage("支付成功","成功购买双倍经验");
  16. }
  17. }
  18. };
  19. // Called when consumption is complete
  20. IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =newIabHelper.OnConsumeFinishedListener() {
  21. publicvoid onConsumeFinished(Purchasepurchase, IabResult result) {
  22. Log.d(TAG,"Consumption finished. Purchase: "+purchase +", result: " +result);
  23. // We know this is the "gas"sku because it's the only onewe consume,
  24. // so we don't check whichsku was consumed. If you havemore than one
  25. //sku, you probably shouldcheck...
  26. if (result.isSuccess()) {
  27. //successfully consumed, so we apply the effects of the item inour
  28. //game world's logic, which in our case means filling the gas tank abit
  29. if(purchase.getSku().equals("coins_100")||purchase.getSku().equals("android.test.purchased")){
  30. showMessage("支付成功","成功购买100猫币");
  31. }
  32. }
  33. else {
  34. complain("Error while consuming: " + result);
  35. }
  36. }
  37. };
  38. // Listener that's called when we finish querying the items weown
  39. IabHelper.QueryInventoryFinishedListener mGotInventoryListener =newIabHelper.QueryInventoryFinishedListener() {
  40. publicvoidonQueryInventoryFinished(IabResult result, Inventory inventory){
  41. Log.d(TAG,"Query inventory finished.");
  42. if (result.isFailure()) {
  43. complain("Failed to query inventory: " +result);
  44. return;
  45. }
  46. Log.d(TAG,"Query inventory was successful.");
  47. if(inventory.hasPurchase("double_income")) {
  48. //查询到有受管理的商品支付成功需要将道具给用户
  49. showMessage("成功Restore双倍金币", "查询到有双倍金币需要恢复");
  50. }elseif(inventory.hasPurchase("cions_100")){
  51. //查询到不受管理的商品支付成功需要将道具消耗掉
  52. showMessage("成功Restore100金币","查询到有100金币需要恢复");
  53. }
  54. }
  55. };
// Callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =newIabHelper.OnIabPurchaseFinishedListener() {publicvoidonIabPurchaseFinished(IabResult result, Purchase purchase) {Log.d(TAG,"Purchase finished: " + result+", purchase: " +purchase);if (result.isFailure()) {// Oh noes!complain("Error purchasing: " + result);return;}Log.d(TAG,"Purchase successful.");if(purchase.getSku().equals("coins_100")||purchase.getSku().equals("android.test.purchased")){mHelper.consumeAsync(purchase, mConsumeFinishedListener);
}elseif (purchase.getSku().equals("double_income")) {
//受管理的商品,开启双倍经验
showMessage("支付成功","成功购买双倍经验");
}}};
// Called when consumption is complete
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =newIabHelper.OnConsumeFinishedListener() {publicvoid onConsumeFinished(Purchasepurchase, IabResult result) {Log.d(TAG,"Consumption finished. Purchase: "+purchase + ", result: " +result);// We know this is the "gas"sku because it's the only onewe consume,// so we don't check whichsku was consumed. If you havemore than one//sku, you probably shouldcheck...if (result.isSuccess()) {//successfully consumed, so we apply the effects of the item inour//game world's logic, which in our case means filling the gas tank abitif(purchase.getSku().equals("coins_100")||purchase.getSku().equals("android.test.purchased")){showMessage("支付成功","成功购买100猫币");}}else {complain("Error while consuming: " + result);}}};// Listener that's called when we finish querying the items weown
IabHelper.QueryInventoryFinishedListener mGotInventoryListener =newIabHelper.QueryInventoryFinishedListener() {publicvoidonQueryInventoryFinished(IabResult result, Inventory inventory){Log.d(TAG,"Query inventory finished.");if (result.isFailure()) {complain("Failed to query inventory: " +result);return;}Log.d(TAG,"Query inventory was successful.");if(inventory.hasPurchase("double_income")) {//查询到有受管理的商品支付成功需要将道具给用户
showMessage("成功Restore双倍金币", "查询到有双倍金币需要恢复");
}elseif(inventory.hasPurchase("cions_100")){
//查询到不受管理的商品支付成功需要将道具消耗掉
showMessage("成功Restore100金币","查询到有100金币需要恢复");
}}};

处理返回Activity后的数据:

[java] view plaincopyprint?

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println(TAG+ "onActivityResult(" + requestCode + "," + resultCode + "," + data);
        if (requestCode == RC_REQUEST) {
         if(resultCode != 0){//这里取得购买结果到google验证 这里的判断处理一定要有 要不然购买中途退出会出错
          purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
                dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
                System.out.println("############"+purchaseData.toString()+"@@@"+dataSignature.toString());
                jniHelper.SendInfo(purchaseData.toString()+"*"+dataSignature.toString());//这里调用到c++的部分与上面的实现方法一样就不说了
         }
         }
        if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
            // not handled, so handle it ourselves (here's where you'd
            // perform any handling of activity results not related to in-app
            // billing...
         
            super.onActivityResult(requestCode, resultCode, data);

}
        else {
            Log.d(TAG, "onActivityResult handled by IABUtil.");
        }   
       
    }

@Override
protectedvoid onActivityResult(int requestCode,int resultCode, Intent data) {
// TODO Auto-generated methodstub
Log.d(TAG, "onActivityResult("+ requestCode + "," +resultCode +"," + data);// Pass on theactivity result to the helper for handlingif(!mHelper.handleActivityResult(requestCode, resultCode, data)){// not handled, so handle it ourselves(here's where you'd// perform any handling of activityresults not related to in-app// billing...super.onActivityResult(requestCode,resultCode, data);}else {Log.d(TAG,"onActivityResult handled by IABUtil.");}
}

退出游戏后销毁IabHelper:

[java] view plaincopyprint?
  1. @Override
  2. protectedvoid onDestroy() {
  3. // TODO Auto-generated methodstub
  4. super.onDestroy();
  5. if (mHelper !=null) mHelper.dispose();
  6. mHelper =null;
  7. }
@Override
protectedvoid onDestroy() {
// TODO Auto-generated methodstub
super.onDestroy();
if (mHelper !=null) mHelper.dispose();mHelper =null;
}

注意:以上代码c++中用到jni java-c++中代码的互相调用需要加上头文件的包含

需要加上平台预编译

#include <jni.h>
#include <android/log.h>
#include "platform/android/jni/JniHelper.h"

coco2d-x游戏开发google play Google In-app-Billing 支付接入相关推荐

  1. C#开发微信门户及应用(32)--微信支付接入和API封装使用

    C#开发微信门户及应用(32)--微信支付接入和API封装使用 在微信的应用上,微信支付是一个比较有用的部分,但也是比较复杂的技术要点,在微商大行其道的年代,自己的商店没有增加微信支付好像也说不过去, ...

  2. 微信小游戏开发实战教程12-广告的开通和接入

    微信小游戏开发实战系列的第12篇, 本节内容主要包括:如何尽快的开通广告功能,以及如何将广告接入到微信小游戏中. 如果你没有任何的游戏开发经验,欢迎阅读我的"人人都能做游戏"系列教 ...

  3. 游戏党福音,Google play游戏明年登录Windows

    整理:.左耳 出品:CSDN 如果你是一名游戏爱好者,你有没有想过有一天能在Windows系统上玩Google play的游戏.虽然这很难以置信,但是它确实发生了.近日,Google Play在202 ...

  4. Notes from Google Play | Google Play 持续助力您的应用和游戏

    作者 / Sarah Karam, Google Play 全球应用合作伙伴关系总监 Google Play 应用合作伙伴关系负责人 -- Sarah Karam,曾与多家公司的开发者会面,倾听他们关 ...

  5. unity 谷歌广告介入_Unity为开发人员发布Google广告

    unity 谷歌广告介入 Everyone loves something new. New ad formats, new advertisers, and new content means mo ...

  6. 【小5聊】发布开发好的google浏览器插件到谷歌应用商店

    将自己开发好的google浏览器插件发布到谷歌应用商店 温馨提示:前提你的网络要能够上国外的网站哦,俗称翻墙 1. 注册为 Chrome 网上应用店开发者 开发者控制台,点击跳转 一步一步填写,就是注 ...

  7. 详述Google针对Android平板App发布的十大开发准则

    2019独角兽企业重金招聘Python工程师标准>>> 在Nexus 7出来之前,Android平板市场的低迷一直让开发者对设计好Android平板上的App兴趣缺缺.为了给自己的平 ...

  8. (转载)如何学好iphone游戏开发

    转自:http://www.cnblogs.com/zilongshanren/archive/2011/09/19/2181558.html 自从发布<如何学习iphone游戏开发>到 ...

  9. 14 岁发现 Bug 兼职游戏开发、拒绝过乔布斯,Dropbox 创始人成为科技创业者的偶像...

    ‍‍ 作者 | 年素清 责编 | 王晓曼 出品 | 程序人生 (ID:coder _life) Drew Houston(安德鲁·豪斯顿)是著名的互联网企业家和云存储行业Dropbox公司的创始人和首 ...

最新文章

  1. 给网站添加icon图标
  2. DivCo: Diverse Conditional Image Synthesis via Contrastive Generative Adversarial Network
  3. Spring整合Struts的几种最常见方式
  4. Facebook批量优化360照片
  5. SAP UI5是如何从浏览器读取语言设置并按照优先级排序的
  6. 整合ssh model $$_javassist_13 cannot be cast to javassist.util.proxy.Proxy
  7. VC/MFC中的CComboBox控件使用详解
  8. c#开发Mongo笔记第五篇
  9. 从properties配置文件中获取到的中文乱码
  10. 下载win7原版ios系统文件
  11. 老旧小区智慧用电改造方案
  12. LQR、LQR-MPC、GP-MPC控制倒立摆
  13. 游怎么用模拟器多开挂机不封号
  14. 计算机和小学科课题,《小学信息技术课堂有效教学的探索》课题研究方案
  15. mysql数据库初始化 error Found option without preceding group in config file
  16. obs噪音抑制调多少合适_(3)阿里国际站OBS申请设置使用教程,OBS音频没有声音怎么办?国际站直播回放如何下载?...
  17. AutoJs学习-录制手指动作
  18. 基于流式输入输出 使用Java借助GSON库 实现对大型asc文件的读入解析 并输出为JSON文件
  19. The package javax.swing is not accessible(java GUI 编程时引用swing包和awt包时会报错怎么办)
  20. java基础-head first java

热门文章

  1. 三伏天如何祛除“月子病”?
  2. Webrtc 多人视频会议系统 服务器 Licode 介绍
  3. 基于微信小程序的电影院购票平台
  4. maven打包--同时将仓库依赖和本地依赖的jar包也打进去
  5. iOS客户端React-Native增量更新实践
  6. 计算机程序设计艺术读后感,计算机程序设计艺术(第1卷)读后感1000字
  7. c语言编程曹冲称象,《曹冲称象》教学设计
  8. 嵩天老师-Python语言程序设计-Python123配套练习测验题目汇总整理
  9. Windows Azure案例:迈阿密市政府使用“云”平台改善服务方案,降低运营成本
  10. Android开发技术网站推荐